From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM10-BN7-obe.outbound.protection.outlook.com (mail-bn7nam10on2090.outbound.protection.outlook.com [40.107.92.90]) by sourceware.org (Postfix) with ESMTPS id D55313858D28 for ; Mon, 24 Apr 2023 12:47:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D55313858D28 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=OARcorp.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=OARcorp.com ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=CRKnWbsOaUi5uxe1iGtvRicgI1EGDCJrWVpTOjMVhyPFr+azkVSAwQ38mEpbY9L2zGyumTxPy0cFOd1c70VcnI6XjNwwAvlNHHBu8Brbt2YhuELoEnvxj2XyXUQVg3YUeGtBSNLmD6jblKLsdjXUO1N5Jyje3r0X1hkwi4o00CQrz41wYE1mkuf9M1c9M6uydvMr6CuQWGnZEKVrFY0dNUKyBl0FlNW/3Hm2NEoI+LQHaNOwV0CTcnRc+xeXD5j+1bRFkvYGy1fzTwoG51fYN6yJfTkYM7VH+M0uiIfDr7vLE8p27kqKFhrHDtFaI6bNgqTz835jQ5qPRi1ZqulORQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=aLDReAt40e0E1DBoOTcyJvBcmylqPT06VoGUNj9sJzA=; b=YANrLLNVF9nU4SDDW3n+0u4e0+zX/SLFFZu6DC7u0bIbGVF1dF+U8BqdrLontiGLGn6DcCxyLy3htMfw+anhAJcv9PErVuwGYOHPHJlGBo/KmqzUKbJ4x3+01YNBMx9zEUbzfEfwJKCrm5pMO42LUpqIUdrh+yIa/tUoAkwR8gJklAvm3BZYMlalXLOD4sgIMC0Lr4yOah6gH/Kt/uzVYP3+e9GO5HcNAOFGEOcSDJqpNuA31xYzBBiuCZnv1jmGvEVWiB9aXlArd8yHkjEKh1R/E+k5IFquRIRkMdWNUdlOrTn4XgiCmdsYmMHdB3VxADXGy+E2af1x17m4Uz8hAA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oarcorp.com; dmarc=pass action=none header.from=oarcorp.com; dkim=pass header.d=oarcorp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oarcorp.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=aLDReAt40e0E1DBoOTcyJvBcmylqPT06VoGUNj9sJzA=; b=IsLWVYiwpZW+1NXJ4Wb48F+9AqXxMfdi/Fl7AXvC8Eux6Ijxk3//yP64edQLicgdLgkRe5M2kLza39AyTrxsOu3ZcSUexU7DnR9lfOLpJNJ0XiGfqtAvLbh5qe1A1NZlYRKohSmQLqj4FvFzQUCh9elfTy6S7BoifpTF9sqMMi8= Received: from BN6PR19MB0098.namprd19.prod.outlook.com (2603:10b6:405:69::34) by PH8PR19MB6927.namprd19.prod.outlook.com (2603:10b6:510:22d::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6319.22; Mon, 24 Apr 2023 12:47:18 +0000 Received: from BN6PR19MB0098.namprd19.prod.outlook.com ([fe80::7e1a:e4d3:93c1:d4d0]) by BN6PR19MB0098.namprd19.prod.outlook.com ([fe80::7e1a:e4d3:93c1:d4d0%6]) with mapi id 15.20.6319.033; Mon, 24 Apr 2023 12:47:18 +0000 From: Jennifer Averett To: "newlib@sourceware.org" Subject: Re: [PATCH v2 1/3] newlib: Add FreeBSD files for non LDBL_EQ_DBL support Thread-Topic: [PATCH v2 1/3] newlib: Add FreeBSD files for non LDBL_EQ_DBL support Thread-Index: AQHZc85hgiw9rPhJBEas3KW026/8Bq86LE0AgAA+4CU= Date: Mon, 24 Apr 2023 12:47:17 +0000 Message-ID: References: <20230420212309.2375488-1-jennifer.averett@oarcorp.com> <20230420212309.2375488-2-jennifer.averett@oarcorp.com> In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=OARcorp.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: BN6PR19MB0098:EE_|PH8PR19MB6927:EE_ x-ms-office365-filtering-correlation-id: 7185c214-2673-4fb6-f29e-08db44c2098c x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: EYLwJtBD5f+CLmSLSgs8Q9CoLUYxG3LOdMxQEOM+j83NyR5lo/jy+LAaoYsHtRXZnysoA7A5Me1uZw2NoDdu5sBd+qPFXojfoDPwfldYpbiE/7hLPdhiS818NoCpUw2K99yXNtvGz8tEFRtHCK0QC4PnSWgff7PmbZcEpMvScfnHWmJIKdGNQvrhgMTPUIy+67hLBUVMnFN1uAYkiQr2uj1M4Q1ZebjYhmto/hng7xEeQmJqRrL1BYxQhWvFXdw2MY0zGEQsk2WcoajRaAf5Bge4/dAUfSuSe3qSM6XgDEc6EDOUWkFrblRcOsmph20VyN5WVkbRXxmDWIcXengJXxKWt2z9mHvHFz9SGA4ScsKwQq4eOt+o5X9InMJxir85wOo+TnWrmo8ZN5kk/HcMD4b4gDboVgxQZ8GRGocvBEywrK22MEjrmO0ApUF1CTeRBpvWKpWxkCwdw9buhAkF7sstUHOj/0pmgiZAotRwBx5Qlvb7knSm4LBGRfnbDs8FBVe4DxPhYOU5hIQ++HP5ux1NKV2ytkwk2YO59ju1l9veaUScpS5jj4LHjnWzLdO3/KOkN1rQ7M+TMT2n91oBlH4lthSV9zt9vgYUA9X2X4917VMHYlHVzzRCf7qxdS+NH1K8BG7oD2EHnnW4A+4nbqgKggRCGjUEWS9YvCH50R0= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BN6PR19MB0098.namprd19.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230028)(366004)(396003)(39830400003)(346002)(42606007)(136003)(376002)(451199021)(19627235002)(38070700005)(40140700001)(86362001)(33656002)(8936002)(478600001)(122000001)(41300700001)(8676002)(38100700002)(5660300002)(30864003)(52536014)(2906002)(66446008)(64756008)(55016003)(6916009)(66476007)(66556008)(316002)(83380400001)(91956017)(76116006)(6506007)(66946007)(9686003)(53546011)(186003)(26005)(966005)(7696005)(66574015)(71200400001)(21314003)(559001)(579004)(357404004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?Windows-1252?Q?U/sONcbajB13tXj3V3Yf8mQDOA2u6jQvRUptqPrk7Dc2jOBdjsvvLl41?= =?Windows-1252?Q?VN6AjK00+dHOR10lS7SK3ILV8z+bYZoTryaArTCZ2IaYh7sCDQZRMG6v?= =?Windows-1252?Q?r/YkxS2csXbNahU09rRmwVh0Bs7BEOCpFrHMH2tJ/snLm/6FslQ9aIFC?= =?Windows-1252?Q?PTPQYHGAeDYJ/s1XPE6mIXt0nlLTSGXmORD7TxuBXXSGQUIX3iyXX3Vf?= =?Windows-1252?Q?J2KLyDvY/TVYUxyFHeChG+opF9q4d9w1OH3YvCIi3eZ8SniyksYhr8JF?= =?Windows-1252?Q?ompz8iAWL4eO1pAlanPN+aFwZB3ax6edaNXiGjN/pOGWf6CTaA63AoCo?= =?Windows-1252?Q?EASGWvsDboUspyG+fvjg8bjNf3AITVRfUdFD/EnLbay9imTihLJhcqWR?= =?Windows-1252?Q?A2fR8ct/2hN1TtdbfWzlSm4ExbvKWlmFbtyZ9eFqSh1b2WmFqpZ7LoBp?= =?Windows-1252?Q?rn0nkKps5ltXaoNO4vvZfmAdPsYPajf1jkIx4X22vJgpk7rWXntJc0mx?= =?Windows-1252?Q?ey7Qb2zjTq6q/CCek0uanEnTwEdMyaKFbzmXbOOKs3JA2uUQsyAqh58u?= =?Windows-1252?Q?tT3sOy8LuaTf0XmksYmfsk8WmCZ1jgIzDusLQYQNhCgsj/nEwuMKpLlP?= =?Windows-1252?Q?DQ7ZEP3oQCXp6NVNN75OAyHEIW/qSDnKe8OJbWK4x8Lo45lyDckFkGmu?= =?Windows-1252?Q?i+IlEPgJZfESUy99a6Chn9/yP8jt+9vq9hnaasTFz4gUdlE/IZWyTqrC?= =?Windows-1252?Q?fx6XLnt+BKkJ3wB5L7MDHdVeW8RaqGY5zZsNitt227TrxM3NjTMfLuYb?= =?Windows-1252?Q?TAa8rvLfxvalOKWIKZG4MCy4kZdstPNMASESE22+CCy59syrAnZvp2+a?= =?Windows-1252?Q?nG7BDWgLrhk3j9PSY851eoz6sPmtibqePAtSm/nR+t6fp9/bvV4rXZFG?= =?Windows-1252?Q?sQdLnwqAN7fPeUmmJmeewg4UICQZmXHbZa7zOViwWsjUOWFRYuJ6QWw/?= =?Windows-1252?Q?Uk6vhPAGlDZ8MTDEi+8kAsCqCEb52Ge0xPZEAmbqTNmLfT8EKOGKURk5?= =?Windows-1252?Q?BN6Wia18bIOMRDtq7npje44ayT98egUJxloFafFPBAVjHR8tdBl+uvm+?= =?Windows-1252?Q?X7C5UnJQMHZxi2WLVbxmQry2+tVAAt55wCx7rJL/Ub3WpfLfqjBggLk/?= =?Windows-1252?Q?6Q0BREAhOqETGO1uK0HMllZICsHPCQzvvdrthMLsGwHyFaEEcGxYSJdR?= =?Windows-1252?Q?c6DA+pju0WtMZT9KJmE9buSEq7E4NSKCqwS01N9h8AndvFyRewYFh1hF?= =?Windows-1252?Q?DMbAnHn8QTOc7AXRRsvp/s42qkKwJ8UXAY8dCqTzWNzUEsjImUG3zKu7?= =?Windows-1252?Q?FFVnsWwEaJedBLePlK3UYtqoNGn3weKFpq5C7wPUZOYjeyInQzBIWygW?= =?Windows-1252?Q?fI5DFbiN4kFa0zHSJ/6PnEFppK2zT0Tctt82B3/F0K8YyORrPUCznqoa?= =?Windows-1252?Q?hTU0vmlnmTeu5ubwVCdK9HD8Y3Qx8Av7oNkr63JiUtmvOHGAfrmoOclK?= =?Windows-1252?Q?1njSSmt9BFJFiwyNhAxusyFzBHB2+CxfEI6+LocIExv+Pw9BxQbkmsPL?= =?Windows-1252?Q?gSE2EgKoYJGQXfbc1C60Yl3MflvQAvO7H+Wp3g47y1mPbxrCdPI4FZOX?= =?Windows-1252?Q?2gj6B6ARF94=3D?= Content-Type: text/plain; charset="Windows-1252" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: oarcorp.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: BN6PR19MB0098.namprd19.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7185c214-2673-4fb6-f29e-08db44c2098c X-MS-Exchange-CrossTenant-originalarrivaltime: 24 Apr 2023 12:47:17.7477 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 7bdf32a6-03de-4c70-a71b-8665ba1294e3 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: +XpJEgVWxKX6RTUi5tymDD4eTsZrhVAcLGheZN3TEmkcEfTnQCVX9KmcL8rKgjmRUaDTpeK18xFnt6+F+L9jSQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH8PR19MB6927 X-Spam-Status: No, score=-10.4 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_ASCII_DIVIDERS,KAM_LOTSOFHASH,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SCC_5_SHORT_WORD_LINES,SPF_HELO_PASS,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Sorry I didn't get those errors my builds. I'll add that into the two file= s. Thanks Jennifer ________________________________________ From: Corinna Vinschen Sent: Monday, April 24, 2023 3:51 AM To: Jennifer Averett Cc: newlib@sourceware.org Subject: Re: [PATCH v2 1/3] newlib: Add FreeBSD files for non LDBL_EQ_DBL s= upport Hi Jennifer, On Apr 20 16:23, Jennifer Averett wrote: > FreeBSD files to add long double support for i386, > aarch64 and x86_64. Building on Cygwin, I'm ewncountering a few errors: newlib/libm/ld/s_ilogbl.c: In function =91ilogbl=92: newlib/libm/ld/s_ilogbl.c:26:9: error: unknown type name =91uint64_t=92 26 | uint64_t m; | ^~~~~~~~ newlib/libm/ld/s_ilogbl.c:21:1: note: =91uint64_t=92 is defined in header = =91=92; did you forget to =91#include =92? 20 | #include "fpmath.h" +++ |+#include 21 | newlib/libm/ld/s_rintl.c: In function =91rintl=92: CC libm/complex/libm_a-creal.o newlib/libm/ld/s_rintl.c:60:9: error: unknown type name =91uint32_t=92 60 | uint32_t expsign; | ^~~~~~~~ newlib/libm/ld/s_rintl.c:36:1: note: =91uint32_t=92 is defined in header = =91=92; did you forget to =91#include =92? 35 | #include "fpmath.h" +++ |+#include 36 | newlib/libm/ld/s_ilogbl.c: In function =91ilogbl=92: newlib/libm/ld/s_ilogbl.c:26:9: error: unknown type name =91uint64_t=92 26 | uint64_t m; | ^~~~~~~~ newlib/libm/ld/s_ilogbl.c:21:1: note: =91uint64_t=92 is defined in header = =91=92; did you forget to =91#include =92? 20 | #include "fpmath.h" +++ |+#include 21 | Adding #include actually fixes them. Thanks, Corinna > --- > newlib/libc/include/sys/endian.h | 177 ++++ > newlib/libc/machine/aarch64/machine/_fpmath.h | 58 ++ > newlib/libc/machine/i386/machine/_fpmath.h | 56 ++ > newlib/libc/machine/x86_64/machine/_fpmath.h | 57 ++ > newlib/libm/ld/e_acoshl.c | 89 ++ > newlib/libm/ld/e_acosl.c | 87 ++ > newlib/libm/ld/e_asinl.c | 77 ++ > newlib/libm/ld/e_atan2l.c | 120 +++ > newlib/libm/ld/e_atanhl.c | 74 ++ > newlib/libm/ld/e_coshl.c | 132 +++ > newlib/libm/ld/e_fmodl.c | 149 +++ > newlib/libm/ld/e_lgammal.c | 25 + > newlib/libm/ld/e_remainderl.c | 40 + > newlib/libm/ld/e_sinhl.c | 134 +++ > newlib/libm/ld/fpmath.h | 82 ++ > newlib/libm/ld/math_private.h | 924 ++++++++++++++++++ > newlib/libm/ld/s_asinhl.c | 91 ++ > newlib/libm/ld/s_atanl.c | 85 ++ > newlib/libm/ld/s_cbrtl.c | 143 +++ > newlib/libm/ld/s_ceill.c | 101 ++ > newlib/libm/ld/s_copysignl.c | 44 + > newlib/libm/ld/s_cosl.c | 102 ++ > newlib/libm/ld/s_fabsl.c | 45 + > newlib/libm/ld/s_fdim.c | 48 + > newlib/libm/ld/s_floorl.c | 101 ++ > newlib/libm/ld/s_fmal.c | 274 ++++++ > newlib/libm/ld/s_fmaxl.c | 57 ++ > newlib/libm/ld/s_fminl.c | 57 ++ > newlib/libm/ld/s_frexpl.c | 64 ++ > newlib/libm/ld/s_ilogbl.c | 53 + > newlib/libm/ld/s_llrintl.c | 9 + > newlib/libm/ld/s_llroundl.c | 11 + > newlib/libm/ld/s_logbl.c | 54 + > newlib/libm/ld/s_lrint.c | 60 ++ > newlib/libm/ld/s_lrintl.c | 9 + > newlib/libm/ld/s_lround.c | 70 ++ > newlib/libm/ld/s_lroundl.c | 11 + > newlib/libm/ld/s_modfl.c | 103 ++ > newlib/libm/ld/s_nearbyint.c | 61 ++ > newlib/libm/ld/s_nextafterl.c | 80 ++ > newlib/libm/ld/s_nexttoward.c | 72 ++ > newlib/libm/ld/s_nexttowardf.c | 59 ++ > newlib/libm/ld/s_remquol.c | 173 ++++ > newlib/libm/ld/s_rintl.c | 92 ++ > newlib/libm/ld/s_roundl.c | 64 ++ > newlib/libm/ld/s_scalbln.c | 56 ++ > newlib/libm/ld/s_scalbnl.c | 49 + > newlib/libm/ld/s_sinl.c | 95 ++ > newlib/libm/ld/s_tanhl.c | 174 ++++ > newlib/libm/ld/s_tanl.c | 97 ++ > newlib/libm/ld/s_truncl.c | 68 ++ > newlib/libm/ld128/b_tgammal.c | 57 ++ > newlib/libm/ld128/e_lgammal_r.c | 330 +++++++ > newlib/libm/ld128/e_powl.c | 443 +++++++++ > newlib/libm/ld128/e_rem_pio2l.h | 135 +++ > newlib/libm/ld128/invtrig.c | 102 ++ > newlib/libm/ld128/invtrig.h | 115 +++ > newlib/libm/ld128/k_cosl.c | 59 ++ > newlib/libm/ld128/k_expl.h | 324 ++++++ > newlib/libm/ld128/k_sinl.c | 59 ++ > newlib/libm/ld128/s_erfl.c | 329 +++++++ > newlib/libm/ld128/s_exp2l.c | 429 ++++++++ > newlib/libm/ld128/s_expl.c | 326 ++++++ > newlib/libm/ld128/s_logl.c | 740 ++++++++++++++ > newlib/libm/ld80/b_expl.c | 113 +++ > newlib/libm/ld80/b_logl.c | 375 +++++++ > newlib/libm/ld80/b_tgammal.c | 419 ++++++++ > newlib/libm/ld80/e_lgammal_r.c | 358 +++++++ > newlib/libm/ld80/e_powl.c | 662 +++++++++++++ > newlib/libm/ld80/e_rem_pio2l.h | 143 +++ > newlib/libm/ld80/invtrig.c | 84 ++ > newlib/libm/ld80/invtrig.h | 116 +++ > newlib/libm/ld80/k_cosl.c | 78 ++ > newlib/libm/ld80/k_cospil.h | 42 + > newlib/libm/ld80/k_expl.h | 301 ++++++ > newlib/libm/ld80/k_sinl.c | 62 ++ > newlib/libm/ld80/k_sinpil.h | 42 + > newlib/libm/ld80/s_cospil.c | 129 +++ > newlib/libm/ld80/s_erfl.c | 337 +++++++ > newlib/libm/ld80/s_exp2l.c | 290 ++++++ > newlib/libm/ld80/s_expl.c | 279 ++++++ > newlib/libm/ld80/s_logl.c | 722 ++++++++++++++ > newlib/libm/ld80/s_sinpil.c | 140 +++ > 83 files changed, 13153 insertions(+) > create mode 100644 newlib/libc/include/sys/endian.h > create mode 100644 newlib/libc/machine/aarch64/machine/_fpmath.h > create mode 100644 newlib/libc/machine/i386/machine/_fpmath.h > create mode 100644 newlib/libc/machine/x86_64/machine/_fpmath.h > create mode 100644 newlib/libm/ld/e_acoshl.c > create mode 100644 newlib/libm/ld/e_acosl.c > create mode 100644 newlib/libm/ld/e_asinl.c > create mode 100644 newlib/libm/ld/e_atan2l.c > create mode 100644 newlib/libm/ld/e_atanhl.c > create mode 100644 newlib/libm/ld/e_coshl.c > create mode 100644 newlib/libm/ld/e_fmodl.c > create mode 100644 newlib/libm/ld/e_lgammal.c > create mode 100644 newlib/libm/ld/e_remainderl.c > create mode 100644 newlib/libm/ld/e_sinhl.c > create mode 100644 newlib/libm/ld/fpmath.h > create mode 100644 newlib/libm/ld/math_private.h > create mode 100644 newlib/libm/ld/s_asinhl.c > create mode 100644 newlib/libm/ld/s_atanl.c > create mode 100644 newlib/libm/ld/s_cbrtl.c > create mode 100644 newlib/libm/ld/s_ceill.c > create mode 100644 newlib/libm/ld/s_copysignl.c > create mode 100644 newlib/libm/ld/s_cosl.c > create mode 100644 newlib/libm/ld/s_fabsl.c > create mode 100644 newlib/libm/ld/s_fdim.c > create mode 100644 newlib/libm/ld/s_floorl.c > create mode 100644 newlib/libm/ld/s_fmal.c > create mode 100644 newlib/libm/ld/s_fmaxl.c > create mode 100644 newlib/libm/ld/s_fminl.c > create mode 100644 newlib/libm/ld/s_frexpl.c > create mode 100644 newlib/libm/ld/s_ilogbl.c > create mode 100644 newlib/libm/ld/s_llrintl.c > create mode 100644 newlib/libm/ld/s_llroundl.c > create mode 100644 newlib/libm/ld/s_logbl.c > create mode 100644 newlib/libm/ld/s_lrint.c > create mode 100644 newlib/libm/ld/s_lrintl.c > create mode 100644 newlib/libm/ld/s_lround.c > create mode 100644 newlib/libm/ld/s_lroundl.c > create mode 100644 newlib/libm/ld/s_modfl.c > create mode 100644 newlib/libm/ld/s_nearbyint.c > create mode 100644 newlib/libm/ld/s_nextafterl.c > create mode 100644 newlib/libm/ld/s_nexttoward.c > create mode 100644 newlib/libm/ld/s_nexttowardf.c > create mode 100644 newlib/libm/ld/s_remquol.c > create mode 100644 newlib/libm/ld/s_rintl.c > create mode 100644 newlib/libm/ld/s_roundl.c > create mode 100644 newlib/libm/ld/s_scalbln.c > create mode 100644 newlib/libm/ld/s_scalbnl.c > create mode 100644 newlib/libm/ld/s_sinl.c > create mode 100644 newlib/libm/ld/s_tanhl.c > create mode 100644 newlib/libm/ld/s_tanl.c > create mode 100644 newlib/libm/ld/s_truncl.c > create mode 100644 newlib/libm/ld128/b_tgammal.c > create mode 100644 newlib/libm/ld128/e_lgammal_r.c > create mode 100644 newlib/libm/ld128/e_powl.c > create mode 100644 newlib/libm/ld128/e_rem_pio2l.h > create mode 100644 newlib/libm/ld128/invtrig.c > create mode 100644 newlib/libm/ld128/invtrig.h > create mode 100644 newlib/libm/ld128/k_cosl.c > create mode 100644 newlib/libm/ld128/k_expl.h > create mode 100644 newlib/libm/ld128/k_sinl.c > create mode 100644 newlib/libm/ld128/s_erfl.c > create mode 100644 newlib/libm/ld128/s_exp2l.c > create mode 100644 newlib/libm/ld128/s_expl.c > create mode 100644 newlib/libm/ld128/s_logl.c > create mode 100644 newlib/libm/ld80/b_expl.c > create mode 100644 newlib/libm/ld80/b_logl.c > create mode 100644 newlib/libm/ld80/b_tgammal.c > create mode 100644 newlib/libm/ld80/e_lgammal_r.c > create mode 100644 newlib/libm/ld80/e_powl.c > create mode 100644 newlib/libm/ld80/e_rem_pio2l.h > create mode 100644 newlib/libm/ld80/invtrig.c > create mode 100644 newlib/libm/ld80/invtrig.h > create mode 100644 newlib/libm/ld80/k_cosl.c > create mode 100644 newlib/libm/ld80/k_cospil.h > create mode 100644 newlib/libm/ld80/k_expl.h > create mode 100644 newlib/libm/ld80/k_sinl.c > create mode 100644 newlib/libm/ld80/k_sinpil.h > create mode 100644 newlib/libm/ld80/s_cospil.c > create mode 100644 newlib/libm/ld80/s_erfl.c > create mode 100644 newlib/libm/ld80/s_exp2l.c > create mode 100644 newlib/libm/ld80/s_expl.c > create mode 100644 newlib/libm/ld80/s_logl.c > create mode 100644 newlib/libm/ld80/s_sinpil.c > > diff --git a/newlib/libc/include/sys/endian.h b/newlib/libc/include/sys/e= ndian.h > new file mode 100644 > index 000000000..d91c442e9 > --- /dev/null > +++ b/newlib/libc/include/sys/endian.h > @@ -0,0 +1,177 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2002 Thomas Moestl > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + * > + * $FreeBSD$ > + */ > + > +#ifndef _SYS_ENDIAN_H_ > +#define _SYS_ENDIAN_H_ > + > +#include > +#include > +#include > + > +#ifndef _UINT8_T_DECLARED > +typedef __uint8_t uint8_t; > +#define _UINT8_T_DECLARED > +#endif > + > +#ifndef _UINT16_T_DECLARED > +typedef __uint16_t uint16_t; > +#define _UINT16_T_DECLARED > +#endif > + > +#ifndef _UINT32_T_DECLARED > +typedef __uint32_t uint32_t; > +#define _UINT32_T_DECLARED > +#endif > + > +#ifndef _UINT64_T_DECLARED > +typedef __uint64_t uint64_t; > +#define _UINT64_T_DECLARED > +#endif > + > +/* > + * Note: While tempting to try to avoid namespace pollution from this fi= le, > + * several software packages assume these marcos are defined, even when = it > + * defines _POSIX_C_SOURCE to request an unpolluted namespace. > + */ > + > +/* > + * General byte order swapping functions. > + */ > +#define bswap16(x) __bswap16(x) > +#define bswap32(x) __bswap32(x) > +#define bswap64(x) __bswap64(x) > + > +/* Alignment-agnostic encode/decode bytestream to/from little/big endian= . */ > +static __inline uint16_t > +be16dec(const void *pp) > +{ > + uint8_t const *p =3D (uint8_t const *)pp; > + > + return ((p[0] << 8) | p[1]); > +} > + > +static __inline uint32_t > +be32dec(const void *pp) > +{ > + uint8_t const *p =3D (uint8_t const *)pp; > + > + return (((unsigned)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3])= ; > +} > + > +static __inline uint64_t > +be64dec(const void *pp) > +{ > + uint8_t const *p =3D (uint8_t const *)pp; > + > + return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4)); > +} > + > +static __inline uint16_t > +le16dec(const void *pp) > +{ > + uint8_t const *p =3D (uint8_t const *)pp; > + > + return ((p[1] << 8) | p[0]); > +} > + > +static __inline uint32_t > +le32dec(const void *pp) > +{ > + uint8_t const *p =3D (uint8_t const *)pp; > + > + return (((unsigned)p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0])= ; > +} > + > +static __inline uint64_t > +le64dec(const void *pp) > +{ > + uint8_t const *p =3D (uint8_t const *)pp; > + > + return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p)); > +} > + > +static __inline void > +be16enc(void *pp, uint16_t u) > +{ > + uint8_t *p =3D (uint8_t *)pp; > + > + p[0] =3D (u >> 8) & 0xff; > + p[1] =3D u & 0xff; > +} > + > +static __inline void > +be32enc(void *pp, uint32_t u) > +{ > + uint8_t *p =3D (uint8_t *)pp; > + > + p[0] =3D (u >> 24) & 0xff; > + p[1] =3D (u >> 16) & 0xff; > + p[2] =3D (u >> 8) & 0xff; > + p[3] =3D u & 0xff; > +} > + > +static __inline void > +be64enc(void *pp, uint64_t u) > +{ > + uint8_t *p =3D (uint8_t *)pp; > + > + be32enc(p, (uint32_t)(u >> 32)); > + be32enc(p + 4, (uint32_t)(u & 0xffffffffU)); > +} > + > +static __inline void > +le16enc(void *pp, uint16_t u) > +{ > + uint8_t *p =3D (uint8_t *)pp; > + > + p[0] =3D u & 0xff; > + p[1] =3D (u >> 8) & 0xff; > +} > + > +static __inline void > +le32enc(void *pp, uint32_t u) > +{ > + uint8_t *p =3D (uint8_t *)pp; > + > + p[0] =3D u & 0xff; > + p[1] =3D (u >> 8) & 0xff; > + p[2] =3D (u >> 16) & 0xff; > + p[3] =3D (u >> 24) & 0xff; > +} > + > +static __inline void > +le64enc(void *pp, uint64_t u) > +{ > + uint8_t *p =3D (uint8_t *)pp; > + > + le32enc(p, (uint32_t)(u & 0xffffffffU)); > + le32enc(p + 4, (uint32_t)(u >> 32)); > +} > +#endif /* _SYS_ENDIAN_H_ */ > diff --git a/newlib/libc/machine/aarch64/machine/_fpmath.h b/newlib/libc/= machine/aarch64/machine/_fpmath.h > new file mode 100644 > index 000000000..71d0a7152 > --- /dev/null > +++ b/newlib/libc/machine/aarch64/machine/_fpmath.h > @@ -0,0 +1,58 @@ > +/*- > + * Copyright (c) 2002, 2003 David Schultz > + * Copyright (2) 2014 The FreeBSD Foundation > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + * > + * $FreeBSD$ > + */ > + > +union IEEEl2bits { > + long double e; > + struct { > + unsigned long manl :64; > + unsigned long manh :48; > + unsigned int exp :15; > + unsigned int sign :1; > + } bits; > + /* TODO andrew: Check the packing here */ > + struct { > + unsigned long manl :64; > + unsigned long manh :48; > + unsigned int expsign :16; > + } xbits; > +}; > + > +#define LDBL_NBIT 0 > +#define LDBL_IMPLICIT_NBIT > +#define mask_nbit_l(u) ((void)0) > + > +#define LDBL_MANH_SIZE 48 > +#define LDBL_MANL_SIZE 64 > + > +#define LDBL_TO_ARRAY32(u, a) do { \ > + (a)[0] =3D (uint32_t)(u).bits.manl; \ > + (a)[1] =3D (uint32_t)((u).bits.manl >> 32); \ > + (a)[2] =3D (uint32_t)(u).bits.manh; \ > + (a)[3] =3D (uint32_t)((u).bits.manh >> 32); \ > +} while(0) > diff --git a/newlib/libc/machine/i386/machine/_fpmath.h b/newlib/libc/mac= hine/i386/machine/_fpmath.h > new file mode 100644 > index 000000000..874439c34 > --- /dev/null > +++ b/newlib/libc/machine/i386/machine/_fpmath.h > @@ -0,0 +1,56 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2002, 2003 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + * > + * $FreeBSD$ > + */ > + > +union IEEEl2bits { > + long double e; > + struct { > + unsigned int manl :32; > + unsigned int manh :32; > + unsigned int exp :15; > + unsigned int sign :1; > + unsigned int junk :16; > + } bits; > + struct { > + unsigned long long man :64; > + unsigned int expsign :16; > + unsigned int junk :16; > + } xbits; > +}; > + > +#define LDBL_NBIT 0x80000000 > +#define mask_nbit_l(u) ((u).bits.manh &=3D ~LDBL_NBIT) > + > +#define LDBL_MANH_SIZE 32 > +#define LDBL_MANL_SIZE 32 > + > +#define LDBL_TO_ARRAY32(u, a) do { \ > + (a)[0] =3D (uint32_t)(u).bits.manl; \ > + (a)[1] =3D (uint32_t)(u).bits.manh; \ > +} while (0) > diff --git a/newlib/libc/machine/x86_64/machine/_fpmath.h b/newlib/libc/m= achine/x86_64/machine/_fpmath.h > new file mode 100644 > index 000000000..8be7b7dba > --- /dev/null > +++ b/newlib/libc/machine/x86_64/machine/_fpmath.h > @@ -0,0 +1,57 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2002, 2003 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + * > + * $FreeBSD$ > + */ > + > +union IEEEl2bits { > + long double e; > + struct { > + unsigned int manl :32; > + unsigned int manh :32; > + unsigned int exp :15; > + unsigned int sign :1; > + unsigned int junkl :16; > + unsigned int junkh :32; > + } bits; > + struct { > + unsigned long man :64; > + unsigned int expsign :16; > + unsigned long junk :48; > + } xbits; > +}; > + > +#define LDBL_NBIT 0x80000000 > +#define mask_nbit_l(u) ((u).bits.manh &=3D ~LDBL_NBIT) > + > +#define LDBL_MANH_SIZE 32 > +#define LDBL_MANL_SIZE 32 > + > +#define LDBL_TO_ARRAY32(u, a) do { \ > + (a)[0] =3D (uint32_t)(u).bits.manl; \ > + (a)[1] =3D (uint32_t)(u).bits.manh; \ > +} while (0) > diff --git a/newlib/libm/ld/e_acoshl.c b/newlib/libm/ld/e_acoshl.c > new file mode 100644 > index 000000000..b9f3aed67 > --- /dev/null > +++ b/newlib/libm/ld/e_acoshl.c > @@ -0,0 +1,89 @@ > +/* from: FreeBSD: head/lib/msun/src/e_acosh.c 176451 2008-02-22 02:30:36= Z das */ > + > +/* @(#)e_acosh.c 1.3 95/01/18 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See e_acosh.c for complete comments. > + * > + * Converted to long double by David Schultz and > + * Bruce D. Evans. > + */ > + > +#include > +#ifdef __i386__ > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +/* EXP_LARGE is the threshold above which we use acosh(x) ~=3D log(2x). = */ > +#if LDBL_MANT_DIG =3D=3D 64 > +#define EXP_LARGE 34 > +#elif LDBL_MANT_DIG =3D=3D 113 > +#define EXP_LARGE 58 > +#else > +#error "Unsupported long double format" > +#endif > + > +#if LDBL_MAX_EXP !=3D 0x4000 > +/* We also require the usual expsign encoding. */ > +#error "Unsupported long double format" > +#endif > + > +#define BIAS (LDBL_MAX_EXP - 1) > + > +static const double > +one =3D 1.0; > + > +#if LDBL_MANT_DIG =3D=3D 64 > +static const union IEEEl2bits > +u_ln2 =3D LD80C(0xb17217f7d1cf79ac, -1, 6.93147180559945309417e-1L); > +#define ln2 u_ln2.e > +#elif LDBL_MANT_DIG =3D=3D 113 > +static const long double > +ln2 =3D 6.93147180559945309417232121458176568e-1L; /* 0x162e42fefa39= ef35793c7673007e6.0p-113 */ > +#else > +#error "Unsupported long double format" > +#endif > + > +long double > +acoshl(long double x) > +{ > + long double t; > + int16_t hx; > + > + ENTERI(); > + GET_LDBL_EXPSIGN(hx, x); > + if (hx < 0x3fff) { /* x < 1, or misnormal */ > + RETURNI((x-x)/(x-x)); > + } else if (hx >=3D BIAS + EXP_LARGE) { /* x >=3D LARGE */ > + if (hx >=3D 0x7fff) { /* x is inf, NaN or misnormal */ > + RETURNI(x+x); > + } else > + RETURNI(logl(x)+ln2); /* acosh(huge)=3Dlog(2x), or misnor= mal */ > + } else if (hx =3D=3D 0x3fff && x =3D=3D 1) { > + RETURNI(0.0); /* acosh(1) =3D 0 */ > + } else if (hx >=3D 0x4000) { /* LARGE > x >=3D 2, or misnormal= */ > + t=3Dx*x; > + RETURNI(logl(2.0*x-one/(x+sqrtl(t-one)))); > + } else { /* 1 + t =3D x-one; > + RETURNI(log1pl(t+sqrtl(2.0*t+t*t))); > + } > +} > diff --git a/newlib/libm/ld/e_acosl.c b/newlib/libm/ld/e_acosl.c > new file mode 100644 > index 000000000..d33c8feda > --- /dev/null > +++ b/newlib/libm/ld/e_acosl.c > @@ -0,0 +1,87 @@ > + > +/* @(#)e_acos.c 1.3 95/01/18 */ > +/* FreeBSD: head/lib/msun/src/e_acos.c 176451 2008-02-22 02:30:36Z das *= / > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See comments in e_acos.c. > + * Converted to long double by David Schultz . > + */ > + > +#include > + > +#include "invtrig.h" > +#include "math.h" > +#include "math_private.h" > + > +static const long double > +one=3D 1.00000000000000000000e+00; > + > +#ifdef __i386__ > +/* XXX Work around the fact that gcc truncates long double constants on = i386 */ > +static volatile double > +pi1 =3D 3.14159265358979311600e+00, /* 0x1.921fb54442d18p+1 */ > +pi2 =3D 1.22514845490862001043e-16; /* 0x1.1a80000000000p-53 */ > +#define pi ((long double)pi1 + pi2) > +#else > +static const long double > +pi =3D 3.14159265358979323846264338327950280e+00L; > +#endif > + > +long double > +acosl(long double x) > +{ > + union IEEEl2bits u; > + long double z,p,q,r,w,s,c,df; > + int16_t expsign, expt; > + u.e =3D x; > + expsign =3D u.xbits.expsign; > + expt =3D expsign & 0x7fff; > + if(expt >=3D BIAS) { /* |x| >=3D 1 */ > + if(expt=3D=3DBIAS && ((u.bits.manh&~LDBL_NBIT)|u.bits.manl)=3D= =3D0) { > + if (expsign>0) return 0.0; /* acos(1) =3D 0 */ > + else return pi+2.0*pio2_lo; /* acos(-1)=3D pi */ > + } > + return (x-x)/(x-x); /* acos(|x|>1) is NaN */ > + } > + if(expt + if(expt + z =3D x*x; > + p =3D P(z); > + q =3D Q(z); > + r =3D p/q; > + return pio2_hi - (x - (pio2_lo-x*r)); > + } else if (expsign<0) { /* x < -0.5 */ > + z =3D (one+x)*0.5; > + p =3D P(z); > + q =3D Q(z); > + s =3D sqrtl(z); > + r =3D p/q; > + w =3D r*s-pio2_lo; > + return pi - 2.0*(s+w); > + } else { /* x > 0.5 */ > + z =3D (one-x)*0.5; > + s =3D sqrtl(z); > + u.e =3D s; > + u.bits.manl =3D 0; > + df =3D u.e; > + c =3D (z-df*df)/(s+df); > + p =3D P(z); > + q =3D Q(z); > + r =3D p/q; > + w =3D r*s+c; > + return 2.0*(df+w); > + } > +} > diff --git a/newlib/libm/ld/e_asinl.c b/newlib/libm/ld/e_asinl.c > new file mode 100644 > index 000000000..a85765f1b > --- /dev/null > +++ b/newlib/libm/ld/e_asinl.c > @@ -0,0 +1,77 @@ > + > +/* @(#)e_asin.c 1.3 95/01/18 */ > +/* FreeBSD: head/lib/msun/src/e_asin.c 176451 2008-02-22 02:30:36Z das *= / > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See comments in e_asin.c. > + * Converted to long double by David Schultz . > + */ > + > +#include > + > +#include "invtrig.h" > +#include "math.h" > +#include "math_private.h" > + > +static const long double > +one =3D 1.00000000000000000000e+00, > +huge =3D 1.000e+300; > + > +long double > +asinl(long double x) > +{ > + union IEEEl2bits u; > + long double t=3D0.0,w,p,q,c,r,s; > + int16_t expsign, expt; > + u.e =3D x; > + expsign =3D u.xbits.expsign; > + expt =3D expsign & 0x7fff; > + if(expt >=3D BIAS) { /* |x|>=3D 1 */ > + if(expt=3D=3DBIAS && ((u.bits.manh&~LDBL_NBIT)|u.bits.manl)= =3D=3D0) > + /* asin(1)=3D+-pi/2 with inexact */ > + return x*pio2_hi+x*pio2_lo; > + return (x-x)/(x-x); /* asin(|x|>1) is NaN */ > + } else if (expt + if(expt + if(huge+x>one) return x;/* return x with inexact if x!=3D0*= / > + } > + t =3D x*x; > + p =3D P(t); > + q =3D Q(t); > + w =3D p/q; > + return x+x*w; > + } > + /* 1> |x|>=3D 0.5 */ > + w =3D one-fabsl(x); > + t =3D w*0.5; > + p =3D P(t); > + q =3D Q(t); > + s =3D sqrtl(t); > + if(u.bits.manh>=3DTHRESH) { /* if |x| is close to 1 */ > + w =3D p/q; > + t =3D pio2_hi-(2.0*(s+s*w)-pio2_lo); > + } else { > + u.e =3D s; > + u.bits.manl =3D 0; > + w =3D u.e; > + c =3D (t-w*w)/(s+w); > + r =3D p/q; > + p =3D 2.0*s*r-(pio2_lo-2.0*c); > + q =3D pio4_hi-2.0*w; > + t =3D pio4_hi-(p-q); > + } > + if(expsign>0) return t; else return -t; > +} > diff --git a/newlib/libm/ld/e_atan2l.c b/newlib/libm/ld/e_atan2l.c > new file mode 100644 > index 000000000..94ebdec54 > --- /dev/null > +++ b/newlib/libm/ld/e_atan2l.c > @@ -0,0 +1,120 @@ > + > +/* @(#)e_atan2.c 1.3 95/01/18 */ > +/* FreeBSD: head/lib/msun/src/e_atan2.c 176451 2008-02-22 02:30:36Z das = */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See comments in e_atan2.c. > + * Converted to long double by David Schultz . > + */ > + > +#include > + > +#include "invtrig.h" > +#include "math.h" > +#include "math_private.h" > + > +static volatile long double > +tiny =3D 1.0e-300; > +static const long double > +zero =3D 0.0; > + > +#ifdef __i386__ > +/* XXX Work around the fact that gcc truncates long double constants on = i386 */ > +static volatile double > +pi1 =3D 3.14159265358979311600e+00, /* 0x1.921fb54442d18p+1 */ > +pi2 =3D 1.22514845490862001043e-16; /* 0x1.1a80000000000p-53 */ > +#define pi ((long double)pi1 + pi2) > +#else > +static const long double > +pi =3D 3.14159265358979323846264338327950280e+00L; > +#endif > + > +long double > +atan2l(long double y, long double x) > +{ > + union IEEEl2bits ux, uy; > + long double z; > + int32_t k,m; > + int16_t exptx, expsignx, expty, expsigny; > + > + uy.e =3D y; > + expsigny =3D uy.xbits.expsign; > + expty =3D expsigny & 0x7fff; > + ux.e =3D x; > + expsignx =3D ux.xbits.expsign; > + exptx =3D expsignx & 0x7fff; > + > + if ((exptx=3D=3DBIAS+LDBL_MAX_EXP && > + ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl)!=3D0) || /* x is N= aN */ > + (expty=3D=3DBIAS+LDBL_MAX_EXP && > + ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl)!=3D0)) /* y is N= aN */ > + return nan_mix(x, y); > + if (expsignx=3D=3DBIAS && ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl)= =3D=3D0) > + return atanl(y); /* x=3D1.0 = */ > + m =3D ((expsigny>>15)&1)|((expsignx>>14)&2); /* 2*sign(x)+sign= (y) */ > + > + /* when y =3D 0 */ > + if(expty=3D=3D0 && ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl)=3D=3D0)= { > + switch(m) { > + case 0: > + case 1: return y; /* atan(+-0,+anything)=3D+-0 */ > + case 2: return pi+tiny;/* atan(+0,-anything) =3D pi */ > + case 3: return -pi-tiny;/* atan(-0,-anything) =3D-pi */ > + } > + } > + /* when x =3D 0 */ > + if(exptx=3D=3D0 && ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl)=3D=3D0) > + return (expsigny<0)? -pio2_hi-tiny: pio2_hi+tiny; > + > + /* when x is INF */ > + if(exptx=3D=3DBIAS+LDBL_MAX_EXP) { > + if(expty=3D=3DBIAS+LDBL_MAX_EXP) { > + switch(m) { > + case 0: return pio2_hi*0.5+tiny;/* atan(+INF,+INF) */ > + case 1: return -pio2_hi*0.5-tiny;/* atan(-INF,+INF) */ > + case 2: return 1.5*pio2_hi+tiny;/*atan(+INF,-INF)*/ > + case 3: return -1.5*pio2_hi-tiny;/*atan(-INF,-INF)*/ > + } > + } else { > + switch(m) { > + case 0: return zero ; /* atan(+...,+INF) */ > + case 1: return -zero ; /* atan(-...,+INF) */ > + case 2: return pi+tiny ; /* atan(+...,-INF) */ > + case 3: return -pi-tiny ; /* atan(-...,-INF) */ > + } > + } > + } > + /* when y is INF */ > + if(expty=3D=3DBIAS+LDBL_MAX_EXP) > + return (expsigny<0)? -pio2_hi-tiny: pio2_hi+tiny; > + > + /* compute y/x */ > + k =3D expty-exptx; > + if(k > LDBL_MANT_DIG+2) { /* |y/x| huge */ > + z=3Dpio2_hi+pio2_lo; > + m&=3D1; > + } > + else if(expsignx<0&&k<-LDBL_MANT_DIG-2) z=3D0.0; /* |y/x| tiny, x<= 0 */ > + else z=3Datanl(fabsl(y/x)); /* safe to do y/x */ > + switch (m) { > + case 0: return z ; /* atan(+,+) */ > + case 1: return -z ; /* atan(-,+) */ > + case 2: return pi-(z-pi_lo);/* atan(+,-) */ > + default: /* case 3 */ > + return (z-pi_lo)-pi;/* atan(-,-) */ > + } > +} > diff --git a/newlib/libm/ld/e_atanhl.c b/newlib/libm/ld/e_atanhl.c > new file mode 100644 > index 000000000..11d56ea52 > --- /dev/null > +++ b/newlib/libm/ld/e_atanhl.c > @@ -0,0 +1,74 @@ > +/* from: FreeBSD: head/lib/msun/src/e_atanh.c 176451 2008-02-22 02:30:36= Z das */ > + > +/* @(#)e_atanh.c 1.3 95/01/18 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See e_atanh.c for complete comments. > + * > + * Converted to long double by David Schultz and > + * Bruce D. Evans. > + */ > + > +#include > +#ifdef __i386__ > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +/* EXP_TINY is the threshold below which we use atanh(x) ~=3D x. */ > +#if LDBL_MANT_DIG =3D=3D 64 > +#define EXP_TINY -34 > +#elif LDBL_MANT_DIG =3D=3D 113 > +#define EXP_TINY -58 > +#else > +#error "Unsupported long double format" > +#endif > + > +#if LDBL_MAX_EXP !=3D 0x4000 > +/* We also require the usual expsign encoding. */ > +#error "Unsupported long double format" > +#endif > + > +#define BIAS (LDBL_MAX_EXP - 1) > + > +static const double one =3D 1.0, huge =3D 1e300; > +static const double zero =3D 0.0; > + > +long double > +atanhl(long double x) > +{ > + long double t; > + uint16_t hx, ix; > + > + ENTERI(); > + GET_LDBL_EXPSIGN(hx, x); > + ix =3D hx & 0x7fff; > + if (ix >=3D 0x3fff) /* |x| >=3D 1, or NaN or misnorma= l */ > + RETURNI(fabsl(x) =3D=3D 1 ? x / zero : (x - x) / (x - x)); > + if (ix < BIAS + EXP_TINY && (huge + x) > zero) > + RETURNI(x); /* x is tiny */ > + SET_LDBL_EXPSIGN(x, ix); > + if (ix < 0x3ffe) { /* |x| < 0.5, or misnormal */ > + t =3D x+x; > + t =3D 0.5*log1pl(t+t*x/(one-x)); > + } else > + t =3D 0.5*log1pl((x+x)/(one-x)); > + RETURNI((hx & 0x8000) =3D=3D 0 ? t : -t); > +} > diff --git a/newlib/libm/ld/e_coshl.c b/newlib/libm/ld/e_coshl.c > new file mode 100644 > index 000000000..4e3b28311 > --- /dev/null > +++ b/newlib/libm/ld/e_coshl.c > @@ -0,0 +1,132 @@ > +/* from: FreeBSD: head/lib/msun/src/e_coshl.c XXX */ > + > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See e_cosh.c for complete comments. > + * > + * Converted to long double by Bruce D. Evans. > + */ > + > +#include > +#ifdef __i386__ > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > +#include "k_expl.h" > + > +#if LDBL_MAX_EXP !=3D 0x4000 > +/* We also require the usual expsign encoding. */ > +#error "Unsupported long double format" > +#endif > + > +#define BIAS (LDBL_MAX_EXP - 1) > + > +static const volatile long double huge =3D 0x1p10000L, tiny =3D 0x1p-100= 00L; > +#if LDBL_MANT_DIG =3D=3D 64 > +/* > + * Domain [-1, 1], range ~[-1.8211e-21, 1.8211e-21]: > + * |cosh(x) - c(x)| < 2**-68.8 > + */ > +static const union IEEEl2bits > +C4u =3D LD80C(0xaaaaaaaaaaaaac78, -5, 4.16666666666666682297e-2L); > +#define C4 C4u.e > +static const double > +C2 =3D 0.5, > +C6 =3D 1.3888888888888616e-3, /* 0x16c16c16c16b99.0p-6= 2 */ > +C8 =3D 2.4801587301767953e-5, /* 0x1a01a01a027061.0p-6= 8 */ > +C10 =3D 2.7557319163300398e-7, /* 0x127e4fb6c9b55f.0p-7= 4 */ > +C12 =3D 2.0876768371393075e-9, /* 0x11eed99406a3f4.0p-8= 1 */ > +C14 =3D 1.1469537039374480e-11, /* 0x1938c67cd18c48.0p-8= 9 */ > +C16 =3D 4.8473490896852041e-14; /* 0x1b49c429701e45.0p-9= 7 */ > +#elif LDBL_MANT_DIG =3D=3D 113 > +/* > + * Domain [-1, 1], range ~[-2.3194e-37, 2.3194e-37]: > + * |cosh(x) - c(x)| < 2**-121.69 > + */ > +static const long double > +C4 =3D 4.16666666666666666666666666666666225e-2L, /* 0x15555555555= 55555555555555554e.0p-117L */ > +C6 =3D 1.38888888888888888888888888889434831e-3L, /* 0x16c16c16c16= c16c16c16c16c1dd7a.0p-122L */ > +C8 =3D 2.48015873015873015873015871870962089e-5L, /* 0x1a01a01a01a= 01a01a01a017af2756.0p-128L */ > +C10 =3D 2.75573192239858906525574318600800201e-7L, /* 0x127e4fb7789= f5c72ef01c8a040640.0p-134L */ > +C12 =3D 2.08767569878680989791444691755468269e-9L, /* 0x11eed8eff8d= 897b543d0679607399.0p-141L */ > +C14=3D 1.14707455977297247387801189650495351e-11L, /* 0x193974a8c07= c9d24ae169a7fa9b54.0p-149L */ > +C16 =3D 4.77947733238737883626416876486279985e-14L; /* 0x1ae7f3e733b= 814d4e1b90f5727fe4.0p-157L */ > +static const double > +C2 =3D 0.5, > +C18 =3D 1.5619206968597871e-16, /* 0x16827863b9900b.0p-1= 05 */ > +C20 =3D 4.1103176218528049e-19, /* 0x1e542ba3d3c269.0p-1= 14 */ > +C22 =3D 8.8967926401641701e-22, /* 0x10ce399542a014.0p-1= 22 */ > +C24 =3D 1.6116681626523904e-24, /* 0x1f2c981d1f0cb7.0p-1= 32 */ > +C26 =3D 2.5022374732804632e-27; /* 0x18c7ecf8b2c4a0.0p-1= 41 */ > +#else > +#error "Unsupported long double format" > +#endif /* LDBL_MANT_DIG =3D=3D 64 */ > + > +/* log(2**16385 - 0.5) rounded up: */ > +static const float > +o_threshold =3D 1.13572168e4; /* 0xb174de.0p-10 */ > + > +long double > +coshl(long double x) > +{ > + long double hi,lo,x2,x4; > +#if LDBL_MANT_DIG =3D=3D 113 > + double dx2; > +#endif > + uint16_t ix; > + > + GET_LDBL_EXPSIGN(ix,x); > + ix &=3D 0x7fff; > + > + /* x is INF or NaN */ > + if(ix>=3D0x7fff) return x*x; > + > + ENTERI(); > + > + /* |x| < 1, return 1 or c(x) */ > + if(ix<0x3fff) { > + if (ix + RETURNI(1+tiny); /* cosh(tiny) =3D 1(+) with inexact= */ > + x2 =3D x*x; > +#if LDBL_MANT_DIG =3D=3D 64 > + x4 =3D x2*x2; > + RETURNI(((C16*x2 + C14)*x4 + (C12*x2 + C10))*(x4*x4*x2) + > + ((C8*x2 + C6)*x2 + C4)*x4 + C2*x2 + 1); > +#elif LDBL_MANT_DIG =3D=3D 113 > + dx2 =3D x2; > + RETURNI((((((((((((C26*dx2 + C24)*dx2 + C22)*dx2 + > + C20)*x2 + C18)*x2 + > + C16)*x2 + C14)*x2 + C12)*x2 + C10)*x2 + C8)*x2 + C6)*x2 + > + C4)*(x2*x2) + C2*x2 + 1); > +#endif > + } > + > + /* |x| in [1, 64), return accurate exp(|x|)/2+1/exp(|x|)/2 */ > + if (ix < 0x4005) { > + k_hexpl(fabsl(x), &hi, &lo); > + RETURNI(lo + 0.25/(hi + lo) + hi); > + } > + > + /* |x| in [64, o_threshold], return correctly-overflowing exp(|x|)/2= */ > + if (fabsl(x) <=3D o_threshold) > + RETURNI(hexpl(fabsl(x))); > + > + /* |x| > o_threshold, cosh(x) overflow */ > + RETURNI(huge*huge); > +} > diff --git a/newlib/libm/ld/e_fmodl.c b/newlib/libm/ld/e_fmodl.c > new file mode 100644 > index 000000000..ad3bcc34c > --- /dev/null > +++ b/newlib/libm/ld/e_fmodl.c > @@ -0,0 +1,149 @@ > +/* @(#)e_fmod.c 1.3 95/01/18 */ > +/*- > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > +#include > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +#define BIAS (LDBL_MAX_EXP - 1) > + > +#if LDBL_MANL_SIZE > 32 > +typedef uint64_t manl_t; > +#else > +typedef uint32_t manl_t; > +#endif > + > +#if LDBL_MANH_SIZE > 32 > +typedef uint64_t manh_t; > +#else > +typedef uint32_t manh_t; > +#endif > + > +/* > + * These macros add and remove an explicit integer bit in front of the > + * fractional mantissa, if the architecture doesn't have such a bit by > + * default already. > + */ > +#ifdef LDBL_IMPLICIT_NBIT > +#define SET_NBIT(hx) ((hx) | (1ULL << LDBL_MANH_SIZE)) > +#define HFRAC_BITS LDBL_MANH_SIZE > +#else > +#define SET_NBIT(hx) (hx) > +#define HFRAC_BITS (LDBL_MANH_SIZE - 1) > +#endif > + > +#define MANL_SHIFT (LDBL_MANL_SIZE - 1) > + > +static const long double one =3D 1.0, Zero[] =3D {0.0, -0.0,}; > + > +/* > + * fmodl(x,y) > + * Return x mod y in exact arithmetic > + * Method: shift and subtract > + * > + * Assumptions: > + * - The low part of the mantissa fits in a manl_t exactly. > + * - The high part of the mantissa fits in an int64_t with enough room > + * for an explicit integer bit in front of the fractional bits. > + */ > +long double > +fmodl(long double x, long double y) > +{ > + union IEEEl2bits ux, uy; > + int64_t hx,hz; /* We need a carry bit even if LDBL_MANH_SIZE is 32= . */ > + manh_t hy; > + manl_t lx,ly,lz; > + int ix,iy,n,sx; > + > + ux.e =3D x; > + uy.e =3D y; > + sx =3D ux.bits.sign; > + > + /* purge off exception values */ > + if((uy.bits.exp|uy.bits.manh|uy.bits.manl)=3D=3D0 || /* y=3D0 */ > + (ux.bits.exp =3D=3D BIAS + LDBL_MAX_EXP) || /* or x not fi= nite */ > + (uy.bits.exp =3D=3D BIAS + LDBL_MAX_EXP && > + ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl)!=3D0)) /* or y is NaN = */ > + return nan_mix_op(x, y, *)/nan_mix_op(x, y, *); > + if(ux.bits.exp<=3Duy.bits.exp) { > + if((ux.bits.exp + (ux.bits.manh<=3Duy.bits.manh && > + (ux.bits.manh + ux.bits.manl + return x; /* |x|<|y| return x or x-y */ > + } > + if(ux.bits.manh=3D=3Duy.bits.manh && ux.bits.manl=3D=3Duy.bits.= manl) { > + return Zero[sx]; /* |x|=3D|y| return x*0*/ > + } > + } > + > + /* determine ix =3D ilogb(x) */ > + if(ux.bits.exp =3D=3D 0) { /* subnormal x */ > + ux.e *=3D 0x1.0p512; > + ix =3D ux.bits.exp - (BIAS + 512); > + } else { > + ix =3D ux.bits.exp - BIAS; > + } > + > + /* determine iy =3D ilogb(y) */ > + if(uy.bits.exp =3D=3D 0) { /* subnormal y */ > + uy.e *=3D 0x1.0p512; > + iy =3D uy.bits.exp - (BIAS + 512); > + } else { > + iy =3D uy.bits.exp - BIAS; > + } > + > + /* set up {hx,lx}, {hy,ly} and align y to x */ > + hx =3D SET_NBIT(ux.bits.manh); > + hy =3D SET_NBIT(uy.bits.manh); > + lx =3D ux.bits.manl; > + ly =3D uy.bits.manl; > + > + /* fix point fmod */ > + n =3D ix - iy; > + > + while(n--) { > + hz=3Dhx-hy;lz=3Dlx-ly; if(lx + if(hz<0){hx =3D hx+hx+(lx>>MANL_SHIFT); lx =3D lx+lx;} > + else { > + if ((hz|lz)=3D=3D0) /* return sign(x)*0 */ > + return Zero[sx]; > + hx =3D hz+hz+(lz>>MANL_SHIFT); lx =3D lz+lz; > + } > + } > + hz=3Dhx-hy;lz=3Dlx-ly; if(lx + if(hz>=3D0) {hx=3Dhz;lx=3Dlz;} > + > + /* convert back to floating value and restore the sign */ > + if((hx|lx)=3D=3D0) /* return sign(x)*0 */ > + return Zero[sx]; > + while(hx<(1ULL< + hx =3D hx+hx+(lx>>MANL_SHIFT); lx =3D lx+lx; > + iy -=3D 1; > + } > + ux.bits.manh =3D hx; /* The mantissa is truncated here if needed. *= / > + ux.bits.manl =3D lx; > + if (iy < LDBL_MIN_EXP) { > + ux.bits.exp =3D iy + (BIAS + 512); > + ux.e *=3D 0x1p-512; > + } else { > + ux.bits.exp =3D iy + BIAS; > + } > + x =3D ux.e * one; /* create necessary signal */ > + return x; /* exact output */ > +} > diff --git a/newlib/libm/ld/e_lgammal.c b/newlib/libm/ld/e_lgammal.c > new file mode 100644 > index 000000000..ebc2fc78c > --- /dev/null > +++ b/newlib/libm/ld/e_lgammal.c > @@ -0,0 +1,25 @@ > +/* @(#)e_lgamma.c 1.3 95/01/18 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include "math.h" > +#include "math_private.h" > + > +extern int signgam; > + > +long double > +lgammal(long double x) > +{ > + return lgammal_r(x,&signgam); > +} > diff --git a/newlib/libm/ld/e_remainderl.c b/newlib/libm/ld/e_remainderl.= c > new file mode 100644 > index 000000000..4a6786309 > --- /dev/null > +++ b/newlib/libm/ld/e_remainderl.c > @@ -0,0 +1,40 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2008 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > + > +long double > +remainderl(long double x, long double y) > +{ > + int quo; > + > + return (remquol(x, y, &quo)); > +} > diff --git a/newlib/libm/ld/e_sinhl.c b/newlib/libm/ld/e_sinhl.c > new file mode 100644 > index 000000000..38d3df195 > --- /dev/null > +++ b/newlib/libm/ld/e_sinhl.c > @@ -0,0 +1,134 @@ > +/* from: FreeBSD: head/lib/msun/src/e_sinhl.c XXX */ > + > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See e_sinh.c for complete comments. > + * > + * Converted to long double by Bruce D. Evans. > + */ > + > +#include > +#ifdef __i386__ > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > +#include "k_expl.h" > + > +#if LDBL_MAX_EXP !=3D 0x4000 > +/* We also require the usual expsign encoding. */ > +#error "Unsupported long double format" > +#endif > + > +#define BIAS (LDBL_MAX_EXP - 1) > + > +static const long double shuge =3D 0x1p16383L; > +#if LDBL_MANT_DIG =3D=3D 64 > +/* > + * Domain [-1, 1], range ~[-6.6749e-22, 6.6749e-22]: > + * |sinh(x)/x - s(x)| < 2**-70.3 > + */ > +static const union IEEEl2bits > +S3u =3D LD80C(0xaaaaaaaaaaaaaaaa, -3, 1.66666666666666666658e-1L); > +#define S3 S3u.e > +static const double > +S5 =3D 8.3333333333333332e-3, /* 0x11111111111111.0p-5= 9 */ > +S7 =3D 1.9841269841270074e-4, /* 0x1a01a01a01a070.0p-6= 5 */ > +S9 =3D 2.7557319223873889e-6, /* 0x171de3a5565fe6.0p-7= 1 */ > +S11 =3D 2.5052108406704084e-8, /* 0x1ae6456857530f.0p-7= 8 */ > +S13 =3D 1.6059042748655297e-10, /* 0x161245fa910697.0p-8= 5 */ > +S15 =3D 7.6470006914396920e-13, /* 0x1ae7ce4eff2792.0p-9= 3 */ > +S17 =3D 2.8346142308424267e-15; /* 0x19882ce789ffc6.0p-1= 01 */ > +#elif LDBL_MANT_DIG =3D=3D 113 > +/* > + * Domain [-1, 1], range ~[-2.9673e-36, 2.9673e-36]: > + * |sinh(x)/x - s(x)| < 2**-118.0 > + */ > +static const long double > +S3 =3D 1.66666666666666666666666666666666033e-1L, /* 0x15555555555= 55555555555555553b.0p-115L */ > +S5 =3D 8.33333333333333333333333333337643193e-3L, /* 0x11111111111= 1111111111111180f5.0p-119L */ > +S7 =3D 1.98412698412698412698412697391263199e-4L, /* 0x1a01a01a01a= 01a01a01a0176aad11.0p-125L */ > +S9 =3D 2.75573192239858906525574406205464218e-6L, /* 0x171de3a556c= 7338faac243aaa9592.0p-131L */ > +S11 =3D 2.50521083854417187749675637460977997e-8L, /* 0x1ae64567f54= 4e38fe59b3380d7413.0p-138L */ > +S13 =3D 1.60590438368216146368737762431552702e-10L, /* 0x16124613a86= d098059c7620850fc2.0p-145L */ > +S15 =3D 7.64716373181980539786802470969096440e-13L, /* 0x1ae7f3e733b= 814193af09ce723043.0p-153L */ > +S17 =3D 2.81145725434775409870584280722701574e-15L; /* 0x1952c77030c= 36898c3fd0b6dfc562.0p-161L */ > +static const double > +S19=3D 8.2206352435411005e-18, /* 0x12f49b4662b86d.0p-1= 09 */ > +S21=3D 1.9572943931418891e-20, /* 0x171b8f2fab9628.0p-1= 18 */ > +S23 =3D 3.8679983530666939e-23, /* 0x17617002b73afc.0p-1= 27 */ > +S25 =3D 6.5067867911512749e-26; /* 0x1423352626048a.0p-1= 36 */ > +#else > +#error "Unsupported long double format" > +#endif /* LDBL_MANT_DIG =3D=3D 64 */ > + > +/* log(2**16385 - 0.5) rounded up: */ > +static const float > +o_threshold =3D 1.13572168e4; /* 0xb174de.0p-10 */ > + > +long double > +sinhl(long double x) > +{ > + long double hi,lo,x2,x4; > +#if LDBL_MANT_DIG =3D=3D 113 > + double dx2; > +#endif > + double s; > + int16_t ix,jx; > + > + GET_LDBL_EXPSIGN(jx,x); > + ix =3D jx&0x7fff; > + > + /* x is INF or NaN */ > + if(ix>=3D0x7fff) return x+x; > + > + ENTERI(); > + > + s =3D 1; > + if (jx<0) s =3D -1; > + > + /* |x| < 64, return x, s(x), or accurate s*(exp(|x|)/2-1/exp(|x|)/2)= */ > + if (ix<0x4005) { /* |x|<64 */ > + if (ix + if(shuge+x>1) RETURNI(x); /* sinh(tiny) =3D tiny with inex= act */ > + if (ix<0x3fff) { /* |x|<1 */ > + x2 =3D x*x; > +#if LDBL_MANT_DIG =3D=3D 64 > + x4 =3D x2*x2; > + RETURNI(((S17*x2 + S15)*x4 + (S13*x2 + S11))*(x2*x*x4*x4) + > + ((S9*x2 + S7)*x2 + S5)*(x2*x*x2) + S3*(x2*x) + x); > +#elif LDBL_MANT_DIG =3D=3D 113 > + dx2 =3D x2; > + RETURNI(((((((((((S25*dx2 + S23)*dx2 + > + S21)*x2 + S19)*x2 + > + S17)*x2 + S15)*x2 + S13)*x2 + S11)*x2 + S9)*x2 + S7)*x2= + > + S5)* (x2*x*x2) + > + S3*(x2*x) + x); > +#endif > + } > + k_hexpl(fabsl(x), &hi, &lo); > + RETURNI(s*(lo - 0.25/(hi + lo) + hi)); > + } > + > + /* |x| in [64, o_threshold], return correctly-overflowing s*exp(|x|)= /2 */ > + if (fabsl(x) <=3D o_threshold) > + RETURNI(s*hexpl(fabsl(x))); > + > + /* |x| > o_threshold, sinh(x) overflow */ > + return x*shuge; > +} > diff --git a/newlib/libm/ld/fpmath.h b/newlib/libm/ld/fpmath.h > new file mode 100644 > index 000000000..ce935eb40 > --- /dev/null > +++ b/newlib/libm/ld/fpmath.h > @@ -0,0 +1,82 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2003 Mike Barcroft > + * Copyright (c) 2002 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + * > + * $FreeBSD$ > + */ > + > +#ifndef _FPMATH_H_ > +#define _FPMATH_H_ > + > +#include > +#include "_fpmath.h" > + > +#ifndef _IEEE_WORD_ORDER > +#define _IEEE_WORD_ORDER _BYTE_ORDER > +#endif > + > +union IEEEf2bits { > + float f; > + struct { > +#if _BYTE_ORDER =3D=3D _LITTLE_ENDIAN > + unsigned int man :23; > + unsigned int exp :8; > + unsigned int sign :1; > +#else /* _BIG_ENDIAN */ > + unsigned int sign :1; > + unsigned int exp :8; > + unsigned int man :23; > +#endif > + } bits; > +}; > + > +#define DBL_MANH_SIZE 20 > +#define DBL_MANL_SIZE 32 > + > +union IEEEd2bits { > + double d; > + struct { > +#if _BYTE_ORDER =3D=3D _LITTLE_ENDIAN > +#if _IEEE_WORD_ORDER =3D=3D _LITTLE_ENDIAN > + unsigned int manl :32; > +#endif > + unsigned int manh :20; > + unsigned int exp :11; > + unsigned int sign :1; > +#if _IEEE_WORD_ORDER =3D=3D _BIG_ENDIAN > + unsigned int manl :32; > +#endif > +#else /* _BIG_ENDIAN */ > + unsigned int sign :1; > + unsigned int exp :11; > + unsigned int manh :20; > + unsigned int manl :32; > +#endif > + } bits; > +}; > + > +#endif /* !_FPMATH_H */ > diff --git a/newlib/libm/ld/math_private.h b/newlib/libm/ld/math_private.= h > new file mode 100644 > index 000000000..df526e71e > --- /dev/null > +++ b/newlib/libm/ld/math_private.h > @@ -0,0 +1,924 @@ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +/* > + * from: @(#)fdlibm.h 5.1 93/09/24 > + * $FreeBSD$ > + */ > + > +#ifndef _MATH_PRIVATE_H_ > +#define _MATH_PRIVATE_H_ > + > +#include > +#include > + > +/* > + * The original fdlibm code used statements like: > + * n0 =3D ((*(int*)&one)>>29)^1; * index of high word * > + * ix0 =3D *(n0+(int*)&x); * high word of x * > + * ix1 =3D *((1-n0)+(int*)&x); * low word of x * > + * to dig two 32 bit words out of the 64 bit IEEE floating point > + * value. That is non-ANSI, and, moreover, the gcc instruction > + * scheduler gets it wrong. We instead use the following macros. > + * Unlike the original code, we determine the endianness at compile > + * time, not at run time; I don't see much benefit to selecting > + * endianness at run time. > + */ > + > +/* > + * A union which permits us to convert between a double and two 32 bit > + * ints. > + */ > + > +#ifdef __arm__ > +#if defined(__VFP_FP__) || defined(__ARM_EABI__) > +#define IEEE_WORD_ORDER BYTE_ORDER > +#else > +#define IEEE_WORD_ORDER BIG_ENDIAN > +#endif > +#else /* __arm__ */ > +#define IEEE_WORD_ORDER BYTE_ORDER > +#endif > + > +/* A union which permits us to convert between a long double and > + four 32 bit ints. */ > + > +#if IEEE_WORD_ORDER =3D=3D BIG_ENDIAN > + > +typedef union > +{ > + long double value; > + struct { > + u_int32_t mswhi; > + u_int32_t mswlo; > + u_int32_t lswhi; > + u_int32_t lswlo; > + } parts32; > + struct { > + u_int64_t msw; > + u_int64_t lsw; > + } parts64; > +} ieee_quad_shape_type; > + > +#endif > + > +#if IEEE_WORD_ORDER =3D=3D LITTLE_ENDIAN > + > +typedef union > +{ > + long double value; > + struct { > + u_int32_t lswlo; > + u_int32_t lswhi; > + u_int32_t mswlo; > + u_int32_t mswhi; > + } parts32; > + struct { > + u_int64_t lsw; > + u_int64_t msw; > + } parts64; > +} ieee_quad_shape_type; > + > +#endif > + > +#if IEEE_WORD_ORDER =3D=3D BIG_ENDIAN > + > +typedef union > +{ > + double value; > + struct > + { > + u_int32_t msw; > + u_int32_t lsw; > + } parts; > + struct > + { > + u_int64_t w; > + } xparts; > +} ieee_double_shape_type; > + > +#endif > + > +#if IEEE_WORD_ORDER =3D=3D LITTLE_ENDIAN > + > +typedef union > +{ > + double value; > + struct > + { > + u_int32_t lsw; > + u_int32_t msw; > + } parts; > + struct > + { > + u_int64_t w; > + } xparts; > +} ieee_double_shape_type; > + > +#endif > + > +/* Get two 32 bit ints from a double. */ > + > +#define EXTRACT_WORDS(ix0,ix1,d) \ > +do { \ > + ieee_double_shape_type ew_u; \ > + ew_u.value =3D (d); \ > + (ix0) =3D ew_u.parts.msw; \ > + (ix1) =3D ew_u.parts.lsw; \ > +} while (0) > + > +/* Get a 64-bit int from a double. */ > +#define EXTRACT_WORD64(ix,d) \ > +do { \ > + ieee_double_shape_type ew_u; \ > + ew_u.value =3D (d); \ > + (ix) =3D ew_u.xparts.w; \ > +} while (0) > + > +/* Get the more significant 32 bit int from a double. */ > + > +#define GET_HIGH_WORD(i,d) \ > +do { \ > + ieee_double_shape_type gh_u; \ > + gh_u.value =3D (d); \ > + (i) =3D gh_u.parts.msw; \ > +} while (0) > + > +/* Get the less significant 32 bit int from a double. */ > + > +#define GET_LOW_WORD(i,d) \ > +do { \ > + ieee_double_shape_type gl_u; \ > + gl_u.value =3D (d); \ > + (i) =3D gl_u.parts.lsw; \ > +} while (0) > + > +/* Set a double from two 32 bit ints. */ > + > +#define INSERT_WORDS(d,ix0,ix1) \ > +do { \ > + ieee_double_shape_type iw_u; \ > + iw_u.parts.msw =3D (ix0); \ > + iw_u.parts.lsw =3D (ix1); \ > + (d) =3D iw_u.value; \ > +} while (0) > + > +/* Set a double from a 64-bit int. */ > +#define INSERT_WORD64(d,ix) \ > +do { \ > + ieee_double_shape_type iw_u; \ > + iw_u.xparts.w =3D (ix); \ > + (d) =3D iw_u.value; \ > +} while (0) > + > +/* Set the more significant 32 bits of a double from an int. */ > + > +#define SET_HIGH_WORD(d,v) \ > +do { \ > + ieee_double_shape_type sh_u; \ > + sh_u.value =3D (d); \ > + sh_u.parts.msw =3D (v); \ > + (d) =3D sh_u.value; \ > +} while (0) > + > +/* Set the less significant 32 bits of a double from an int. */ > + > +#define SET_LOW_WORD(d,v) \ > +do { \ > + ieee_double_shape_type sl_u; \ > + sl_u.value =3D (d); \ > + sl_u.parts.lsw =3D (v); \ > + (d) =3D sl_u.value; \ > +} while (0) > + > +/* > + * A union which permits us to convert between a float and a 32 bit > + * int. > + */ > + > +typedef union > +{ > + float value; > + /* FIXME: Assumes 32 bit int. */ > + unsigned int word; > +} ieee_float_shape_type; > + > +/* Get a 32 bit int from a float. */ > + > +#define GET_FLOAT_WORD(i,d) \ > +do { \ > + ieee_float_shape_type gf_u; \ > + gf_u.value =3D (d); \ > + (i) =3D gf_u.word; \ > +} while (0) > + > +/* Set a float from a 32 bit int. */ > + > +#define SET_FLOAT_WORD(d,i) \ > +do { \ > + ieee_float_shape_type sf_u; \ > + sf_u.word =3D (i); \ > + (d) =3D sf_u.value; \ > +} while (0) > + > +/* > + * Get expsign and mantissa as 16 bit and 64 bit ints from an 80 bit lon= g > + * double. > + */ > + > +#define EXTRACT_LDBL80_WORDS(ix0,ix1,d) \ > +do { \ > + union IEEEl2bits ew_u; \ > + ew_u.e =3D (d); \ > + (ix0) =3D ew_u.xbits.expsign; \ > + (ix1) =3D ew_u.xbits.man; \ > +} while (0) > + > +/* > + * Get expsign and mantissa as one 16 bit and two 64 bit ints from a 128= bit > + * long double. > + */ > + > +#define EXTRACT_LDBL128_WORDS(ix0,ix1,ix2,d) \ > +do { \ > + union IEEEl2bits ew_u; \ > + ew_u.e =3D (d); \ > + (ix0) =3D ew_u.xbits.expsign; \ > + (ix1) =3D ew_u.xbits.manh; \ > + (ix2) =3D ew_u.xbits.manl; \ > +} while (0) > + > +/* Get expsign as a 16 bit int from a long double. */ > + > +#define GET_LDBL_EXPSIGN(i,d) \ > +do { \ > + union IEEEl2bits ge_u; \ > + ge_u.e =3D (d); \ > + (i) =3D ge_u.xbits.expsign; \ > +} while (0) > + > +/* > + * Set an 80 bit long double from a 16 bit int expsign and a 64 bit int > + * mantissa. > + */ > + > +#define INSERT_LDBL80_WORDS(d,ix0,ix1) \ > +do { \ > + union IEEEl2bits iw_u; \ > + iw_u.xbits.expsign =3D (ix0); \ > + iw_u.xbits.man =3D (ix1); \ > + (d) =3D iw_u.e; \ > +} while (0) > + > +/* > + * Set a 128 bit long double from a 16 bit int expsign and two 64 bit in= ts > + * comprising the mantissa. > + */ > + > +#define INSERT_LDBL128_WORDS(d,ix0,ix1,ix2) \ > +do { \ > + union IEEEl2bits iw_u; \ > + iw_u.xbits.expsign =3D (ix0); \ > + iw_u.xbits.manh =3D (ix1); \ > + iw_u.xbits.manl =3D (ix2); \ > + (d) =3D iw_u.e; \ > +} while (0) > + > +/* Set expsign of a long double from a 16 bit int. */ > + > +#define SET_LDBL_EXPSIGN(d,v) \ > +do { \ > + union IEEEl2bits se_u; \ > + se_u.e =3D (d); \ > + se_u.xbits.expsign =3D (v); \ > + (d) =3D se_u.e; \ > +} while (0) > + > +#ifdef __i386__ > +/* Long double constants are broken on i386. */ > +#define LD80C(m, ex, v) { = \ > + .xbits.man =3D __CONCAT(m, ULL), \ > + .xbits.expsign =3D (0x3fff + (ex)) | ((v) < 0 ? 0x8000 : 0), \ > +} > +#else > +/* The above works on non-i386 too, but we use this to check v. */ > +#define LD80C(m, ex, v) { .e =3D (v), } > +#endif > + > +#ifdef FLT_EVAL_METHOD > +/* > + * Attempt to get strict C99 semantics for assignment with non-C99 compi= lers. > + */ > +#if FLT_EVAL_METHOD =3D=3D 0 || __GNUC__ =3D=3D 0 > +#define STRICT_ASSIGN(type, lval, rval) ((lval) =3D (rval)) > +#else > +#define STRICT_ASSIGN(type, lval, rval) do { \ > + volatile type __lval; \ > + \ > + if (sizeof(type) >=3D sizeof(long double)) \ > + (lval) =3D (rval); \ > + else { \ > + __lval =3D (rval); \ > + (lval) =3D __lval; \ > + } \ > +} while (0) > +#endif > +#endif /* FLT_EVAL_METHOD */ > + > +/* Support switching the mode to FP_PE if necessary. */ > +#if defined(__i386__) && !defined(NO_FPSETPREC) > +#define ENTERI() ENTERIT(long double) > +#define ENTERIT(returntype) \ > + returntype __retval; \ > + fp_prec_t __oprec; \ > + \ > + if ((__oprec =3D fpgetprec()) !=3D FP_PE) \ > + fpsetprec(FP_PE) > +#define RETURNI(x) do { \ > + __retval =3D (x); \ > + if (__oprec !=3D FP_PE) \ > + fpsetprec(__oprec); \ > + RETURNF(__retval); \ > +} while (0) > +#define ENTERV() \ > + fp_prec_t __oprec; \ > + \ > + if ((__oprec =3D fpgetprec()) !=3D FP_PE) \ > + fpsetprec(FP_PE) > +#define RETURNV() do { \ > + if (__oprec !=3D FP_PE) \ > + fpsetprec(__oprec); \ > + return; \ > +} while (0) > +#else > +#define ENTERI() > +#define ENTERIT(x) > +#define RETURNI(x) RETURNF(x) > +#define ENTERV() > +#define RETURNV() return > +#endif > + > +/* Default return statement if hack*_t() is not used. */ > +#define RETURNF(v) return (v) > + > +/* > + * 2sum gives the same result as 2sumF without requiring |a| >=3D |b| or > + * a =3D=3D 0, but is slower. > + */ > +#define _2sum(a, b) do { \ > + __typeof(a) __s, __w; \ > + \ > + __w =3D (a) + (b); \ > + __s =3D __w - (a); \ > + (b) =3D ((a) - (__w - __s)) + ((b) - __s); \ > + (a) =3D __w; \ > +} while (0) > + > +/* > + * 2sumF algorithm. > + * > + * "Normalize" the terms in the infinite-precision expression a + b for > + * the sum of 2 floating point values so that b is as small as possible > + * relative to 'a'. (The resulting 'a' is the value of the expression i= n > + * the same precision as 'a' and the resulting b is the rounding error.) > + * |a| must be >=3D |b| or 0, b's type must be no larger than 'a's type,= and > + * exponent overflow or underflow must not occur. This uses a Theorem o= f > + * Dekker (1971). See Knuth (1981) 4.2.2 Theorem C. The name "TwoSum" > + * is apparently due to Skewchuk (1997). > + * > + * For this to always work, assignment of a + b to 'a' must not retain a= ny > + * extra precision in a + b. This is required by C standards but broken > + * in many compilers. The brokenness cannot be worked around using > + * STRICT_ASSIGN() like we do elsewhere, since the efficiency of this > + * algorithm would be destroyed by non-null strict assignments. (The > + * compilers are correct to be broken -- the efficiency of all floating > + * point code calculations would be destroyed similarly if they forced t= he > + * conversions.) > + * > + * Fortunately, a case that works well can usually be arranged by buildi= ng > + * any extra precision into the type of 'a' -- 'a' should have type floa= t_t, > + * double_t or long double. b's type should be no larger than 'a's type= . > + * Callers should use these types with scopes as large as possible, to > + * reduce their own extra-precision and efficiciency problems. In > + * particular, they shouldn't convert back and forth just to call here. > + */ > +#ifdef DEBUG > +#define _2sumF(a, b) do { \ > + __typeof(a) __w; \ > + volatile __typeof(a) __ia, __ib, __r, __vw; \ > + \ > + __ia =3D (a); \ > + __ib =3D (b); \ > + assert(__ia =3D=3D 0 || fabsl(__ia) >=3D fabsl(__ib)); \ > + \ > + __w =3D (a) + (b); \ > + (b) =3D ((a) - __w) + (b); \ > + (a) =3D __w; \ > + \ > + /* The next 2 assertions are weak if (a) is already long double. */= \ > + assert((long double)__ia + __ib =3D=3D (long double)(a) + (b)); = \ > + __vw =3D __ia + __ib; \ > + __r =3D __ia - __vw; \ > + __r +=3D __ib; \ > + assert(__vw =3D=3D (a) && __r =3D=3D (b)); \ > +} while (0) > +#else /* !DEBUG */ > +#define _2sumF(a, b) do { \ > + __typeof(a) __w; \ > + \ > + __w =3D (a) + (b); \ > + (b) =3D ((a) - __w) + (b); \ > + (a) =3D __w; \ > +} while (0) > +#endif /* DEBUG */ > + > +/* > + * Set x +=3D c, where x is represented in extra precision as a + b. > + * x must be sufficiently normalized and sufficiently larger than c, > + * and the result is then sufficiently normalized. > + * > + * The details of ordering are that |a| must be >=3D |c| (so that (a, c) > + * can be normalized without extra work to swap 'a' with c). The detail= s of > + * the normalization are that b must be small relative to the normalized= 'a'. > + * Normalization of (a, c) makes the normalized c tiny relative to the > + * normalized a, so b remains small relative to 'a' in the result. Howe= ver, > + * b need not ever be tiny relative to 'a'. For example, b might be abo= ut > + * 2**20 times smaller than 'a' to give about 20 extra bits of precision= . > + * That is usually enough, and adding c (which by normalization is about > + * 2**53 times smaller than a) cannot change b significantly. However, > + * cancellation of 'a' with c in normalization of (a, c) may reduce 'a' > + * significantly relative to b. The caller must ensure that significant > + * cancellation doesn't occur, either by having c of the same sign as 'a= ', > + * or by having |c| a few percent smaller than |a|. Pre-normalization o= f > + * (a, b) may help. > + * > + * This is a variant of an algorithm of Kahan (see Knuth (1981) 4.2.2 > + * exercise 19). We gain considerable efficiency by requiring the terms= to > + * be sufficiently normalized and sufficiently increasing. > + */ > +#define _3sumF(a, b, c) do { \ > + __typeof(a) __tmp; \ > + \ > + __tmp =3D (c); \ > + _2sumF(__tmp, (a)); \ > + (b) +=3D (a); \ > + (a) =3D __tmp; \ > +} while (0) > + > +/* > + * Common routine to process the arguments to nan(), nanf(), and nanl(). > + */ > +void _scan_nan(uint32_t *__words, int __num_words, const char *__s); > + > +/* > + * Mix 0, 1 or 2 NaNs. First add 0 to each arg. This normally just tur= ns > + * signaling NaNs into quiet NaNs by setting a quiet bit. We do this > + * because we want to never return a signaling NaN, and also because we > + * don't want the quiet bit to affect the result. Then mix the converte= d > + * args using the specified operation. > + * > + * When one arg is NaN, the result is typically that arg quieted. When = both > + * args are NaNs, the result is typically the quietening of the arg whos= e > + * mantissa is largest after quietening. When neither arg is NaN, the > + * result may be NaN because it is indeterminate, or finite for subseque= nt > + * construction of a NaN as the indeterminate 0.0L/0.0L. > + * > + * Technical complications: the result in bits after rounding to the fin= al > + * precision might depend on the runtime precision and/or on compiler > + * optimizations, especially when different register sets are used for > + * different precisions. Try to make the result not depend on at least = the > + * runtime precision by always doing the main mixing step in long double > + * precision. Try to reduce dependencies on optimizations by adding the > + * the 0's in different precisions (unless everything is in long double > + * precision). > + */ > +#define nan_mix(x, y) (nan_mix_op((x), (y), +)) > +#define nan_mix_op(x, y, op) (((x) + 0.0L) op ((y) + 0)) > + > +#ifdef _COMPLEX_H > + > +/* > + * C99 specifies that complex numbers have the same representation as > + * an array of two elements, where the first element is the real part > + * and the second element is the imaginary part. > + */ > +typedef union { > + float complex f; > + float a[2]; > +} float_complex; > +typedef union { > + double complex f; > + double a[2]; > +} double_complex; > +typedef union { > + long double complex f; > + long double a[2]; > +} long_double_complex; > +#define REALPART(z) ((z).a[0]) > +#define IMAGPART(z) ((z).a[1]) > + > +/* > + * Inline functions that can be used to construct complex values. > + * > + * The C99 standard intends x+I*y to be used for this, but x+I*y is > + * currently unusable in general since gcc introduces many overflow, > + * underflow, sign and efficiency bugs by rewriting I*y as > + * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product. > + * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted > + * to -0.0+I*0.0. > + * > + * The C11 standard introduced the macros CMPLX(), CMPLXF() and CMPLXL() > + * to construct complex values. Compilers that conform to the C99 > + * standard require the following functions to avoid the above issues. > + */ > + > +#ifndef CMPLXF > +static __inline float complex > +CMPLXF(float x, float y) > +{ > + float_complex z; > + > + REALPART(z) =3D x; > + IMAGPART(z) =3D y; > + return (z.f); > +} > +#endif > + > +#ifndef CMPLX > +static __inline double complex > +CMPLX(double x, double y) > +{ > + double_complex z; > + > + REALPART(z) =3D x; > + IMAGPART(z) =3D y; > + return (z.f); > +} > +#endif > + > +#ifndef CMPLXL > +static __inline long double complex > +CMPLXL(long double x, long double y) > +{ > + long_double_complex z; > + > + REALPART(z) =3D x; > + IMAGPART(z) =3D y; > + return (z.f); > +} > +#endif > + > +#endif /* _COMPLEX_H */ > + > +/* > + * The rnint() family rounds to the nearest integer for a restricted ran= ge > + * range of args (up to about 2**MANT_DIG). We assume that the current > + * rounding mode is FE_TONEAREST so that this can be done efficiently. > + * Extra precision causes more problems in practice, and we only central= ize > + * this here to reduce those problems, and have not solved the efficienc= y > + * problems. The exp2() family uses a more delicate version of this tha= t > + * requires extracting bits from the intermediate value, so it is not > + * centralized here and should copy any solution of the efficiency probl= ems. > + */ > + > +static inline double > +rnint(__double_t x) > +{ > + /* > + * This casts to double to kill any extra precision. This depends > + * on the cast being applied to a double_t to avoid compiler bugs > + * (this is a cleaner version of STRICT_ASSIGN()). This is > + * inefficient if there actually is extra precision, but is hard > + * to improve on. We use double_t in the API to minimise conversio= ns > + * for just calling here. Note that we cannot easily change the > + * magic number to the one that works directly with double_t, since > + * the rounding precision is variable at runtime on x86 so the > + * magic number would need to be variable. Assuming that the > + * rounding precision is always the default is too fragile. This > + * and many other complications will move when the default is > + * changed to FP_PE. > + */ > + return ((double)(x + 0x1.8p52) - 0x1.8p52); > +} > + > +static inline float > +rnintf(__float_t x) > +{ > + /* > + * As for rnint(), except we could just call that to handle the > + * extra precision case, usually without losing efficiency. > + */ > + return ((float)(x + 0x1.8p23F) - 0x1.8p23F); > +} > + > +#ifdef LDBL_MANT_DIG > +/* > + * The complications for extra precision are smaller for rnintl() since = it > + * can safely assume that the rounding precision has been increased from > + * its default to FP_PE on x86. We don't exploit that here to get small > + * optimizations from limiting the rangle to double. We just need it fo= r > + * the magic number to work with long doubles. ld128 callers should use > + * rnint() instead of this if possible. ld80 callers should prefer > + * rnintl() since for amd64 this avoids swapping the register set, while > + * for i386 it makes no difference (assuming FP_PE), and for other arche= s > + * it makes little difference. > + */ > +static inline long double > +rnintl(long double x) > +{ > + return (x + __CONCAT(0x1.8p, LDBL_MANT_DIG) / 2 - > + __CONCAT(0x1.8p, LDBL_MANT_DIG) / 2); > +} > +#endif /* LDBL_MANT_DIG */ > + > +/* > + * irint() and i64rint() give the same result as casting to their intege= r > + * return type provided their arg is a floating point integer. They can > + * sometimes be more efficient because no rounding is required. > + */ > +#if defined(amd64) || defined(__i386__) > +#define irint(x) \ > + (sizeof(x) =3D=3D sizeof(float) && \ > + sizeof(__float_t) =3D=3D sizeof(long double) ? irintf(x) : \ > + sizeof(x) =3D=3D sizeof(double) && \ > + sizeof(__double_t) =3D=3D sizeof(long double) ? irintd(x) : \ > + sizeof(x) =3D=3D sizeof(long double) ? irintl(x) : (int)(x)) > +#else > +#define irint(x) ((int)(x)) > +#endif > + > +#define i64rint(x) ((int64_t)(x)) /* only needed for ld128 so= not opt. */ > + > +#if defined(__i386__) > +static __inline int > +irintf(float x) > +{ > + int n; > + > + __asm("fistl %0" : "=3Dm" (n) : "t" (x)); > + return (n); > +} > + > +static __inline int > +irintd(double x) > +{ > + int n; > + > + __asm("fistl %0" : "=3Dm" (n) : "t" (x)); > + return (n); > +} > +#endif > + > +#if defined(__amd64__) || defined(__i386__) > +static __inline int > +irintl(long double x) > +{ > + int n; > + > + __asm("fistl %0" : "=3Dm" (n) : "t" (x)); > + return (n); > +} > +#endif > + > +#ifdef DEBUG > +#if defined(__amd64__) || defined(__i386__) > +#define breakpoint() asm("int $3") > +#else > +#include > + > +#define breakpoint() raise(SIGTRAP) > +#endif > +#endif > + > +/* Write a pari script to test things externally. */ > +#ifdef DOPRINT > +#include > + > +#ifndef DOPRINT_SWIZZLE > +#define DOPRINT_SWIZZLE 0 > +#endif > + > +#ifdef DOPRINT_LD80 > + > +#define DOPRINT_START(xp) do { = \ > + uint64_t __lx; \ > + uint16_t __hx; \ > + \ > + /* Hack to give more-problematic args. */ \ > + EXTRACT_LDBL80_WORDS(__hx, __lx, *xp); \ > + __lx ^=3D DOPRINT_SWIZZLE; \ > + INSERT_LDBL80_WORDS(*xp, __hx, __lx); \ > + printf("x =3D %.21Lg; ", (long double)*xp); \ > +} while (0) > +#define DOPRINT_END1(v) = \ > + printf("y =3D %.21Lg; z =3D 0; show(x, y, z);\n", (long double)(v)) > +#define DOPRINT_END2(hi, lo) = \ > + printf("y =3D %.21Lg; z =3D %.21Lg; show(x, y, z);\n", = \ > + (long double)(hi), (long double)(lo)) > + > +#elif defined(DOPRINT_D64) > + > +#define DOPRINT_START(xp) do { = \ > + uint32_t __hx, __lx; \ > + \ > + EXTRACT_WORDS(__hx, __lx, *xp); \ > + __lx ^=3D DOPRINT_SWIZZLE; \ > + INSERT_WORDS(*xp, __hx, __lx); \ > + printf("x =3D %.21Lg; ", (long double)*xp); \ > +} while (0) > +#define DOPRINT_END1(v) = \ > + printf("y =3D %.21Lg; z =3D 0; show(x, y, z);\n", (long double)(v)) > +#define DOPRINT_END2(hi, lo) = \ > + printf("y =3D %.21Lg; z =3D %.21Lg; show(x, y, z);\n", = \ > + (long double)(hi), (long double)(lo)) > + > +#elif defined(DOPRINT_F32) > + > +#define DOPRINT_START(xp) do { = \ > + uint32_t __hx; \ > + \ > + GET_FLOAT_WORD(__hx, *xp); \ > + __hx ^=3D DOPRINT_SWIZZLE; \ > + SET_FLOAT_WORD(*xp, __hx); \ > + printf("x =3D %.21Lg; ", (long double)*xp); \ > +} while (0) > +#define DOPRINT_END1(v) = \ > + printf("y =3D %.21Lg; z =3D 0; show(x, y, z);\n", (long double)(v)) > +#define DOPRINT_END2(hi, lo) = \ > + printf("y =3D %.21Lg; z =3D %.21Lg; show(x, y, z);\n", = \ > + (long double)(hi), (long double)(lo)) > + > +#else /* !DOPRINT_LD80 && !DOPRINT_D64 (LD128 only) */ > + > +#ifndef DOPRINT_SWIZZLE_HIGH > +#define DOPRINT_SWIZZLE_HIGH 0 > +#endif > + > +#define DOPRINT_START(xp) do { = \ > + uint64_t __lx, __llx; \ > + uint16_t __hx; \ > + \ > + EXTRACT_LDBL128_WORDS(__hx, __lx, __llx, *xp); \ > + __llx ^=3D DOPRINT_SWIZZLE; \ > + __lx ^=3D DOPRINT_SWIZZLE_HIGH; \ > + INSERT_LDBL128_WORDS(*xp, __hx, __lx, __llx); \ > + printf("x =3D %.36Lg; ", (long double)*xp); = \ > +} while (0) > +#define DOPRINT_END1(v) = \ > + printf("y =3D %.36Lg; z =3D 0; show(x, y, z);\n", (long double)(v)) > +#define DOPRINT_END2(hi, lo) = \ > + printf("y =3D %.36Lg; z =3D %.36Lg; show(x, y, z);\n", = \ > + (long double)(hi), (long double)(lo)) > + > +#endif /* DOPRINT_LD80 */ > + > +#else /* !DOPRINT */ > +#define DOPRINT_START(xp) > +#define DOPRINT_END1(v) > +#define DOPRINT_END2(hi, lo) > +#endif /* DOPRINT */ > + > +#define RETURNP(x) do { \ > + DOPRINT_END1(x); \ > + RETURNF(x); \ > +} while (0) > +#define RETURNPI(x) do { \ > + DOPRINT_END1(x); \ > + RETURNI(x); \ > +} while (0) > +#define RETURN2P(x, y) do { \ > + DOPRINT_END2((x), (y)); \ > + RETURNF((x) + (y)); \ > +} while (0) > +#define RETURN2PI(x, y) do { \ > + DOPRINT_END2((x), (y)); \ > + RETURNI((x) + (y)); \ > +} while (0) > +#ifdef STRUCT_RETURN > +#define RETURNSP(rp) do { \ > + if (!(rp)->lo_set) \ > + RETURNP((rp)->hi); \ > + RETURN2P((rp)->hi, (rp)->lo); \ > +} while (0) > +#define RETURNSPI(rp) do { \ > + if (!(rp)->lo_set) \ > + RETURNPI((rp)->hi); \ > + RETURN2PI((rp)->hi, (rp)->lo); \ > +} while (0) > +#endif > +#define SUM2P(x, y) ({ \ > + const __typeof (x) __x =3D (x); \ > + const __typeof (y) __y =3D (y); \ > + \ > + DOPRINT_END2(__x, __y); \ > + __x + __y; \ > +}) > + > +/* > + * ieee style elementary functions > + * > + * We rename functions here to improve other sources' diffability > + * against fdlibm. > + */ > +#define __ieee754_sqrt sqrt > +#define __ieee754_acos acos > +#define __ieee754_acosh acosh > +#define __ieee754_log log > +#define __ieee754_log2 log2 > +#define __ieee754_atanh atanh > +#define __ieee754_asin asin > +#define __ieee754_atan2 atan2 > +#define __ieee754_exp exp > +#define __ieee754_cosh cosh > +#define __ieee754_fmod fmod > +#define __ieee754_pow pow > +#define __ieee754_lgamma lgamma > +#define __ieee754_gamma gamma > +#define __ieee754_lgamma_r lgamma_r > +#define __ieee754_gamma_r gamma_r > +#define __ieee754_log10 log10 > +#define __ieee754_sinh sinh > +#define __ieee754_hypot hypot > +#define __ieee754_j0 j0 > +#define __ieee754_j1 j1 > +#define __ieee754_y0 y0 > +#define __ieee754_y1 y1 > +#define __ieee754_jn jn > +#define __ieee754_yn yn > +#define __ieee754_remainder remainder > +#define __ieee754_scalb scalb > +#define __ieee754_sqrtf sqrtf > +#define __ieee754_acosf acosf > +#define __ieee754_acoshf acoshf > +#define __ieee754_logf logf > +#define __ieee754_atanhf atanhf > +#define __ieee754_asinf asinf > +#define __ieee754_atan2f atan2f > +#define __ieee754_expf expf > +#define __ieee754_coshf coshf > +#define __ieee754_fmodf fmodf > +#define __ieee754_powf powf > +#define __ieee754_lgammaf lgammaf > +#define __ieee754_gammaf gammaf > +#define __ieee754_lgammaf_r lgammaf_r > +#define __ieee754_gammaf_r gammaf_r > +#define __ieee754_log10f log10f > +#define __ieee754_log2f log2f > +#define __ieee754_sinhf sinhf > +#define __ieee754_hypotf hypotf > +#define __ieee754_j0f j0f > +#define __ieee754_j1f j1f > +#define __ieee754_y0f y0f > +#define __ieee754_y1f y1f > +#define __ieee754_jnf jnf > +#define __ieee754_ynf ynf > +#define __ieee754_remainderf remainderf > +#define __ieee754_scalbf scalbf > + > +/* fdlibm kernel function */ > +int __kernel_rem_pio2(double*,double*,int,int,int); > + > +/* double precision kernel functions */ > +#ifndef INLINE_REM_PIO2 > +int __ieee754_rem_pio2(double,double*); > +#endif > +double __kernel_sin(double,double,int); > +double __kernel_cos(double,double); > +double __kernel_tan(double,double,int); > +double __ldexp_exp(double,int); > +#ifdef _COMPLEX_H > +double complex __ldexp_cexp(double complex,int); > +#endif > + > +/* float precision kernel functions */ > +#ifndef INLINE_REM_PIO2F > +int __ieee754_rem_pio2f(float,double*); > +#endif > +#ifndef INLINE_KERNEL_SINDF > +float __kernel_sindf(double); > +#endif > +#ifndef INLINE_KERNEL_COSDF > +float __kernel_cosdf(double); > +#endif > +#ifndef INLINE_KERNEL_TANDF > +float __kernel_tandf(double,int); > +#endif > +float __ldexp_expf(float,int); > +#ifdef _COMPLEX_H > +float complex __ldexp_cexpf(float complex,int); > +#endif > + > +/* long double precision kernel functions */ > +long double __kernel_sinl(long double, long double, int); > +long double __kernel_cosl(long double, long double); > +long double __kernel_tanl(long double, long double, int); > + > +#endif /* !_MATH_PRIVATE_H_ */ > diff --git a/newlib/libm/ld/s_asinhl.c b/newlib/libm/ld/s_asinhl.c > new file mode 100644 > index 000000000..ba28f599c > --- /dev/null > +++ b/newlib/libm/ld/s_asinhl.c > @@ -0,0 +1,91 @@ > +/* from: FreeBSD: head/lib/msun/src/e_acosh.c 176451 2008-02-22 02:30:36= Z das */ > + > +/* @(#)s_asinh.c 5.1 93/09/24 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See s_asinh.c for complete comments. > + * > + * Converted to long double by David Schultz and > + * Bruce D. Evans. > + */ > + > +#include > +#ifdef __i386__ > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +/* EXP_LARGE is the threshold above which we use asinh(x) ~=3D log(2x). = */ > +/* EXP_TINY is the threshold below which we use asinh(x) ~=3D x. */ > +#if LDBL_MANT_DIG =3D=3D 64 > +#define EXP_LARGE 34 > +#define EXP_TINY -34 > +#elif LDBL_MANT_DIG =3D=3D 113 > +#define EXP_LARGE 58 > +#define EXP_TINY -58 > +#else > +#error "Unsupported long double format" > +#endif > + > +#if LDBL_MAX_EXP !=3D 0x4000 > +/* We also require the usual expsign encoding. */ > +#error "Unsupported long double format" > +#endif > + > +#define BIAS (LDBL_MAX_EXP - 1) > + > +static const double > +one =3D 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ > +huge=3D 1.00000000000000000000e+300; > + > +#if LDBL_MANT_DIG =3D=3D 64 > +static const union IEEEl2bits > +u_ln2 =3D LD80C(0xb17217f7d1cf79ac, -1, 6.93147180559945309417e-1L); > +#define ln2 u_ln2.e > +#elif LDBL_MANT_DIG =3D=3D 113 > +static const long double > +ln2 =3D 6.93147180559945309417232121458176568e-1L; /* 0x162e42fefa39= ef35793c7673007e6.0p-113 */ > +#else > +#error "Unsupported long double format" > +#endif > + > +long double > +asinhl(long double x) > +{ > + long double t, w; > + uint16_t hx, ix; > + > + ENTERI(); > + GET_LDBL_EXPSIGN(hx, x); > + ix =3D hx & 0x7fff; > + if (ix >=3D 0x7fff) RETURNI(x+x); /* x is inf, NaN or misnormal */ > + if (ix < BIAS + EXP_TINY) { /* |x| < TINY, or misnormal */ > + if (huge + x > one) RETURNI(x); /* return x inexact except = 0 */ > + } > + if (ix >=3D BIAS + EXP_LARGE) { /* |x| >=3D LARGE, or misnormal *= / > + w =3D logl(fabsl(x))+ln2; > + } else if (ix >=3D 0x4000) { /* LARGE > |x| >=3D 2.0, or misno= rmal */ > + t =3D fabsl(x); > + w =3D logl(2.0*t+one/(sqrtl(x*x+one)+t)); > + } else { /* 2.0 > |x| >=3D TINY, or misnormal */ > + t =3D x*x; > + w =3Dlog1pl(fabsl(x)+t/(one+sqrtl(one+t))); > + } > + RETURNI((hx & 0x8000) =3D=3D 0 ? w : -w); > +} > diff --git a/newlib/libm/ld/s_atanl.c b/newlib/libm/ld/s_atanl.c > new file mode 100644 > index 000000000..ff29c3ce8 > --- /dev/null > +++ b/newlib/libm/ld/s_atanl.c > @@ -0,0 +1,85 @@ > +/* @(#)s_atan.c 5.1 93/09/24 */ > +/* FreeBSD: head/lib/msun/src/s_atan.c 176451 2008-02-22 02:30:36Z das *= / > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See comments in s_atan.c. > + * Converted to long double by David Schultz . > + */ > + > +#include > + > +#include "invtrig.h" > +#include "math.h" > +#include "math_private.h" > + > +static const long double > +one =3D 1.0, > +huge =3D 1.0e300; > + > +long double > +atanl(long double x) > +{ > + union IEEEl2bits u; > + long double w,s1,s2,z; > + int id; > + int16_t expsign, expt; > + int32_t expman; > + > + u.e =3D x; > + expsign =3D u.xbits.expsign; > + expt =3D expsign & 0x7fff; > + if(expt >=3D ATAN_CONST) { /* if |x| is large, atan(x)~=3Dpi= /2 */ > + if(expt =3D=3D BIAS + LDBL_MAX_EXP && > + ((u.bits.manh&~LDBL_NBIT)|u.bits.manl)!=3D0) > + return x+x; /* NaN */ > + if(expsign>0) return atanhi[3]+atanlo[3]; > + else return -atanhi[3]-atanlo[3]; > + } > + /* Extract the exponent and the first few bits of the mantissa. */ > + /* XXX There should be a more convenient way to do this. */ > + expman =3D (expt << 8) | ((u.bits.manh >> (MANH_SIZE - 9)) & 0xff); > + if (expman < ((BIAS - 2) << 8) + 0xc0) { /* |x| < 0.4375 */ > + if (expt < ATAN_LINEAR) { /* if |x| is small, atanl(x)~=3Dx *= / > + if(huge+x>one) return x; /* raise inexact */ > + } > + id =3D -1; > + } else { > + x =3D fabsl(x); > + if (expman < (BIAS << 8) + 0x30) { /* |x| < 1.1875 */ > + if (expman < ((BIAS - 1) << 8) + 0x60) { /* 7/16 <=3D|x|<11/= 16 */ > + id =3D 0; x =3D (2.0*x-one)/(2.0+x); > + } else { /* 11/16<=3D|x|< 19/16 */ > + id =3D 1; x =3D (x-one)/(x+one); > + } > + } else { > + if (expman < ((BIAS + 1) << 8) + 0x38) { /* |x| < 2.4375 */ > + id =3D 2; x =3D (x-1.5)/(one+1.5*x); > + } else { /* 2.4375 <=3D |x| < 2^ATAN_CONST *= / > + id =3D 3; x =3D -1.0/x; > + } > + }} > + /* end of argument reduction */ > + z =3D x*x; > + w =3D z*z; > + /* break sum aT[i]z**(i+1) into odd and even poly */ > + s1 =3D z*T_even(w); > + s2 =3D w*T_odd(w); > + if (id<0) return x - x*(s1+s2); > + else { > + z =3D atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); > + return (expsign<0)? -z:z; > + } > +} > diff --git a/newlib/libm/ld/s_cbrtl.c b/newlib/libm/ld/s_cbrtl.c > new file mode 100644 > index 000000000..b15c96ecd > --- /dev/null > +++ b/newlib/libm/ld/s_cbrtl.c > @@ -0,0 +1,143 @@ > +/*- > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * Copyright (c) 2009-2011, Bruce D. Evans, Steven G. Kargl, David Schul= tz. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * > + * The argument reduction and testing for exceptional cases was > + * written by Steven G. Kargl with input from Bruce D. Evans > + * and David A. Schultz. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > +#ifdef __i386__ > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +#define BIAS (LDBL_MAX_EXP - 1) > + > +static const unsigned > + B1 =3D 709958130; /* B1 =3D (127-127.0/3-0.03306235651)*2**23 */ > + > +long double > +cbrtl(long double x) > +{ > + union IEEEl2bits u, v; > + long double r, s, t, w; > + double dr, dt, dx; > + float ft, fx; > + uint32_t hx; > + uint16_t expsign; > + int k; > + > + u.e =3D x; > + expsign =3D u.xbits.expsign; > + k =3D expsign & 0x7fff; > + > + /* > + * If x =3D +-Inf, then cbrt(x) =3D +-Inf. > + * If x =3D NaN, then cbrt(x) =3D NaN. > + */ > + if (k =3D=3D BIAS + LDBL_MAX_EXP) > + return (x + x); > + > + ENTERI(); > + if (k =3D=3D 0) { > + /* If x =3D +-0, then cbrt(x) =3D +-0. */ > + if ((u.bits.manh | u.bits.manl) =3D=3D 0) > + RETURNI(x); > + /* Adjust subnormal numbers. */ > + u.e *=3D 0x1.0p514; > + k =3D u.bits.exp; > + k -=3D BIAS + 514; > + } else > + k -=3D BIAS; > + u.xbits.expsign =3D BIAS; > + v.e =3D 1; > + > + x =3D u.e; > + switch (k % 3) { > + case 1: > + case -2: > + x =3D 2*x; > + k--; > + break; > + case 2: > + case -1: > + x =3D 4*x; > + k -=3D 2; > + break; > + } > + v.xbits.expsign =3D (expsign & 0x8000) | (BIAS + k / 3); > + > + /* > + * The following is the guts of s_cbrtf, with the handling of > + * special values removed and extra care for accuracy not taken, > + * but with most of the extra accuracy not discarded. > + */ > + > + /* ~5-bit estimate: */ > + fx =3D x; > + GET_FLOAT_WORD(hx, fx); > + SET_FLOAT_WORD(ft, ((hx & 0x7fffffff) / 3 + B1)); > + > + /* ~16-bit estimate: */ > + dx =3D x; > + dt =3D ft; > + dr =3D dt * dt * dt; > + dt =3D dt * (dx + dx + dr) / (dx + dr + dr); > + > + /* ~47-bit estimate: */ > + dr =3D dt * dt * dt; > + dt =3D dt * (dx + dx + dr) / (dx + dr + dr); > + > +#if LDBL_MANT_DIG =3D=3D 64 > + /* > + * dt is cbrtl(x) to ~47 bits (after x has been reduced to 1 <=3D x= < 8). > + * Round it away from zero to 32 bits (32 so that t*t is exact, and > + * away from zero for technical reasons). > + */ > + volatile double vd2 =3D 0x1.0p32; > + volatile double vd1 =3D 0x1.0p-31; > + #define vd ((long double)vd2 + vd1) > + > + t =3D dt + vd - 0x1.0p32; > +#elif LDBL_MANT_DIG =3D=3D 113 > + /* > + * Round dt away from zero to 47 bits. Since we don't trust the 47= , > + * add 2 47-bit ulps instead of 1 to round up. Rounding is slow an= d > + * might be avoidable in this case, since on most machines dt will > + * have been evaluated in 53-bit precision and the technical reason= s > + * for rounding up might not apply to either case in cbrtl() since > + * dt is much more accurate than needed. > + */ > + t =3D dt + 0x2.0p-46 + 0x1.0p60L - 0x1.0p60; > +#else > +#error "Unsupported long double format" > +#endif > + > + /* > + * Final step Newton iteration to 64 or 113 bits with > + * error < 0.667 ulps > + */ > + s=3Dt*t; /* t*t is exact */ > + r=3Dx/s; /* error <=3D 0.5 ulps; |r| < |t|= */ > + w=3Dt+t; /* t+t is exact */ > + r=3D(r-t)/(w+r); /* r-t is exact; w+r ~=3D 3*t */ > + t=3Dt+t*r; /* error <=3D (0.5 + 0.5/3) * ulp= */ > + > + t *=3D v.e; > + RETURNI(t); > +} > diff --git a/newlib/libm/ld/s_ceill.c b/newlib/libm/ld/s_ceill.c > new file mode 100644 > index 000000000..2d1045fe6 > --- /dev/null > +++ b/newlib/libm/ld/s_ceill.c > @@ -0,0 +1,101 @@ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * > + * From: @(#)s_ceil.c 5.1 93/09/24 > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * ceill(x) > + * Return x rounded toward -inf to integral value > + * Method: > + * Bit twiddling. > + * Exception: > + * Inexact flag raised if x not equal to ceill(x). > + */ > + > +#include > +#include > +#include > + > +#include "fpmath.h" > + > +#ifdef LDBL_IMPLICIT_NBIT > +#define MANH_SIZE (LDBL_MANH_SIZE + 1) > +#define INC_MANH(u, c) do { \ > + uint64_t o =3D u.bits.manh; \ > + u.bits.manh +=3D (c); \ > + if (u.bits.manh < o) \ > + u.bits.exp++; \ > +} while (0) > +#else > +#define MANH_SIZE LDBL_MANH_SIZE > +#define INC_MANH(u, c) do { \ > + uint64_t o =3D u.bits.manh; \ > + u.bits.manh +=3D (c); \ > + if (u.bits.manh < o) { \ > + u.bits.exp++; \ > + u.bits.manh |=3D 1llu << (LDBL_MANH_SIZE - 1); \ > + } \ > +} while (0) > +#endif > + > +static const long double huge =3D 1.0e300; > + > +long double > +ceill(long double x) > +{ > + union IEEEl2bits u =3D { .e =3D x }; > + int e =3D u.bits.exp - LDBL_MAX_EXP + 1; > + > + if (e < MANH_SIZE - 1) { > + if (e < 0) { /* raise inexact if x !=3D = 0 */ > + if (huge + x > 0.0) > + if (u.bits.exp > 0 || > + (u.bits.manh | u.bits.manl) !=3D 0) > + u.e =3D u.bits.sign ? -0.0 : 1.0; > + } else { > + uint64_t m =3D ((1llu << MANH_SIZE) - 1) >> (e + 1)= ; > + if (((u.bits.manh & m) | u.bits.manl) =3D=3D 0) > + return (x); /* x is integral */ > + if (!u.bits.sign) { > +#ifdef LDBL_IMPLICIT_NBIT > + if (e =3D=3D 0) > + u.bits.exp++; > + else > +#endif > + INC_MANH(u, 1llu << (MANH_SIZE - e - 1)); > + } > + if (huge + x > 0.0) { /* raise inexact flag */ > + u.bits.manh &=3D ~m; > + u.bits.manl =3D 0; > + } > + } > + } else if (e < LDBL_MANT_DIG - 1) { > + uint64_t m =3D (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1)= ; > + if ((u.bits.manl & m) =3D=3D 0) > + return (x); /* x is integral */ > + if (!u.bits.sign) { > + if (e =3D=3D MANH_SIZE - 1) > + INC_MANH(u, 1); > + else { > + uint64_t o =3D u.bits.manl; > + u.bits.manl +=3D 1llu << (LDBL_MANT_DIG - e= - 1); > + if (u.bits.manl < o) /* got a carry */ > + INC_MANH(u, 1); > + } > + } > + if (huge + x > 0.0) /* raise inexact flag */ > + u.bits.manl &=3D ~m; > + } > + return (u.e); > +} > diff --git a/newlib/libm/ld/s_copysignl.c b/newlib/libm/ld/s_copysignl.c > new file mode 100644 > index 000000000..bd6744705 > --- /dev/null > +++ b/newlib/libm/ld/s_copysignl.c > @@ -0,0 +1,44 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2004 Stefan Farfeleder > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + * > + * $FreeBSD$ > + */ > + > +#include > + > +#include "fpmath.h" > + > +long double > +copysignl(long double x, long double y) > +{ > + union IEEEl2bits ux, uy; > + > + ux.e =3D x; > + uy.e =3D y; > + ux.bits.sign =3D uy.bits.sign; > + return (ux.e); > +} > diff --git a/newlib/libm/ld/s_cosl.c b/newlib/libm/ld/s_cosl.c > new file mode 100644 > index 000000000..3d066483f > --- /dev/null > +++ b/newlib/libm/ld/s_cosl.c > @@ -0,0 +1,102 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2007 Steven G. Kargl > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice unmodified, this list of conditions, and the following > + * disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * Limited testing on pseudorandom numbers drawn within [-2e8:4e8] shows > + * an accuracy of <=3D 0.7412 ULP. > + */ > + > +#include > +#ifdef __i386__ > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > +#if LDBL_MANT_DIG =3D=3D 64 > +#include "../ld80/e_rem_pio2l.h" > +static const union IEEEl2bits > +pio4u =3D LD80C(0xc90fdaa22168c235, -00001, 7.85398163397448309628e-01L= ); > +#define pio4 (pio4u.e) > +#elif LDBL_MANT_DIG =3D=3D 113 > +#include "../ld128/e_rem_pio2l.h" > +long double pio4 =3D 7.85398163397448309615660845819875721e-1L; > +#else > +#error "Unsupported long double format" > +#endif > + > +long double > +cosl(long double x) > +{ > + union IEEEl2bits z; > + int e0; > + long double y[2]; > + long double hi, lo; > + > + z.e =3D x; > + z.bits.sign =3D 0; > + > + /* If x =3D +-0 or x is a subnormal number, then cos(x) =3D 1 */ > + if (z.bits.exp =3D=3D 0) > + return (1.0); > + > + /* If x =3D NaN or Inf, then cos(x) =3D NaN. */ > + if (z.bits.exp =3D=3D 32767) > + return ((x - x) / (x - x)); > + > + ENTERI(); > + > + /* Optimize the case where x is already within range. */ > + if (z.e < pio4) > + RETURNI(__kernel_cosl(z.e, 0)); > + > + e0 =3D __ieee754_rem_pio2l(x, y); > + hi =3D y[0]; > + lo =3D y[1]; > + > + switch (e0 & 3) { > + case 0: > + hi =3D __kernel_cosl(hi, lo); > + break; > + case 1: > + hi =3D - __kernel_sinl(hi, lo, 1); > + break; > + case 2: > + hi =3D - __kernel_cosl(hi, lo); > + break; > + case 3: > + hi =3D __kernel_sinl(hi, lo, 1); > + break; > + } > + > + RETURNI(hi); > +} > diff --git a/newlib/libm/ld/s_fabsl.c b/newlib/libm/ld/s_fabsl.c > new file mode 100644 > index 000000000..5076d8a9b > --- /dev/null > +++ b/newlib/libm/ld/s_fabsl.c > @@ -0,0 +1,45 @@ > +/*- > + * SPDX-License-Identifier: BSD-3-Clause > + * > + * Copyright (c) 2003 Dag-Erling Sm=F8rgrav > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer > + * in this position and unchanged. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * 3. The name of the author may not be used to endorse or promote produ= cts > + * derived from this software without specific prior written permissi= on. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + * > + * $FreeBSD$ > + */ > + > +#include > + > +#include "fpmath.h" > + > +long double > +fabsl(long double x) > +{ > + union IEEEl2bits u; > + > + u.e =3D x; > + u.bits.sign =3D 0; > + return (u.e); > +} > diff --git a/newlib/libm/ld/s_fdim.c b/newlib/libm/ld/s_fdim.c > new file mode 100644 > index 000000000..c40c3e9d3 > --- /dev/null > +++ b/newlib/libm/ld/s_fdim.c > @@ -0,0 +1,48 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2004 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > + > +#define DECL(type, fn) \ > +type \ > +fn(type x, type y) \ > +{ \ > + \ > + if (isnan(x)) \ > + return (x); \ > + if (isnan(y)) \ > + return (y); \ > + return (x > y ? x - y : 0.0); \ > +} > + > +DECL(double, fdim) > +DECL(float, fdimf) > +DECL(long double, fdiml) > diff --git a/newlib/libm/ld/s_floorl.c b/newlib/libm/ld/s_floorl.c > new file mode 100644 > index 000000000..6cec3e781 > --- /dev/null > +++ b/newlib/libm/ld/s_floorl.c > @@ -0,0 +1,101 @@ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * > + * From: @(#)s_floor.c 5.1 93/09/24 > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * floorl(x) > + * Return x rounded toward -inf to integral value > + * Method: > + * Bit twiddling. > + * Exception: > + * Inexact flag raised if x not equal to floorl(x). > + */ > + > +#include > +#include > +#include > + > +#include "fpmath.h" > + > +#ifdef LDBL_IMPLICIT_NBIT > +#define MANH_SIZE (LDBL_MANH_SIZE + 1) > +#define INC_MANH(u, c) do { \ > + uint64_t o =3D u.bits.manh; \ > + u.bits.manh +=3D (c); \ > + if (u.bits.manh < o) \ > + u.bits.exp++; \ > +} while (0) > +#else > +#define MANH_SIZE LDBL_MANH_SIZE > +#define INC_MANH(u, c) do { \ > + uint64_t o =3D u.bits.manh; \ > + u.bits.manh +=3D (c); \ > + if (u.bits.manh < o) { \ > + u.bits.exp++; \ > + u.bits.manh |=3D 1llu << (LDBL_MANH_SIZE - 1); \ > + } \ > +} while (0) > +#endif > + > +static const long double huge =3D 1.0e300; > + > +long double > +floorl(long double x) > +{ > + union IEEEl2bits u =3D { .e =3D x }; > + int e =3D u.bits.exp - LDBL_MAX_EXP + 1; > + > + if (e < MANH_SIZE - 1) { > + if (e < 0) { /* raise inexact if x !=3D = 0 */ > + if (huge + x > 0.0) > + if (u.bits.exp > 0 || > + (u.bits.manh | u.bits.manl) !=3D 0) > + u.e =3D u.bits.sign ? -1.0 : 0.0; > + } else { > + uint64_t m =3D ((1llu << MANH_SIZE) - 1) >> (e + 1)= ; > + if (((u.bits.manh & m) | u.bits.manl) =3D=3D 0) > + return (x); /* x is integral */ > + if (u.bits.sign) { > +#ifdef LDBL_IMPLICIT_NBIT > + if (e =3D=3D 0) > + u.bits.exp++; > + else > +#endif > + INC_MANH(u, 1llu << (MANH_SIZE - e - 1)); > + } > + if (huge + x > 0.0) { /* raise inexact flag */ > + u.bits.manh &=3D ~m; > + u.bits.manl =3D 0; > + } > + } > + } else if (e < LDBL_MANT_DIG - 1) { > + uint64_t m =3D (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1)= ; > + if ((u.bits.manl & m) =3D=3D 0) > + return (x); /* x is integral */ > + if (u.bits.sign) { > + if (e =3D=3D MANH_SIZE - 1) > + INC_MANH(u, 1); > + else { > + uint64_t o =3D u.bits.manl; > + u.bits.manl +=3D 1llu << (LDBL_MANT_DIG - e= - 1); > + if (u.bits.manl < o) /* got a carry */ > + INC_MANH(u, 1); > + } > + } > + if (huge + x > 0.0) /* raise inexact flag */ > + u.bits.manl &=3D ~m; > + } > + return (u.e); > +} > diff --git a/newlib/libm/ld/s_fmal.c b/newlib/libm/ld/s_fmal.c > new file mode 100644 > index 000000000..a379346c1 > --- /dev/null > +++ b/newlib/libm/ld/s_fmal.c > @@ -0,0 +1,274 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2005-2011 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > +#include > +#include > + > +#include "fpmath.h" > + > +/* > + * A struct dd represents a floating-point number with twice the precisi= on > + * of a long double. We maintain the invariant that "hi" stores the hig= h-order > + * bits of the result. > + */ > +struct dd { > + long double hi; > + long double lo; > +}; > + > +/* > + * Compute a+b exactly, returning the exact result in a struct dd. We a= ssume > + * that both a and b are finite, but make no assumptions about their rel= ative > + * magnitudes. > + */ > +static inline struct dd > +dd_add(long double a, long double b) > +{ > + struct dd ret; > + long double s; > + > + ret.hi =3D a + b; > + s =3D ret.hi - a; > + ret.lo =3D (a - (ret.hi - s)) + (b - s); > + return (ret); > +} > + > +/* > + * Compute a+b, with a small tweak: The least significant bit of the > + * result is adjusted into a sticky bit summarizing all the bits that > + * were lost to rounding. This adjustment negates the effects of double > + * rounding when the result is added to another number with a higher > + * exponent. For an explanation of round and sticky bits, see any refer= ence > + * on FPU design, e.g., > + * > + * J. Coonen. An Implementation Guide to a Proposed Standard for > + * Floating-Point Arithmetic. Computer, vol. 13, no. 1, Jan 1980. > + */ > +static inline long double > +add_adjusted(long double a, long double b) > +{ > + struct dd sum; > + union IEEEl2bits u; > + > + sum =3D dd_add(a, b); > + if (sum.lo !=3D 0) { > + u.e =3D sum.hi; > + if ((u.bits.manl & 1) =3D=3D 0) > + sum.hi =3D nextafterl(sum.hi, INFINITY * sum.lo); > + } > + return (sum.hi); > +} > + > +/* > + * Compute ldexp(a+b, scale) with a single rounding error. It is assumed > + * that the result will be subnormal, and care is taken to ensure that > + * double rounding does not occur. > + */ > +static inline long double > +add_and_denormalize(long double a, long double b, int scale) > +{ > + struct dd sum; > + int bits_lost; > + union IEEEl2bits u; > + > + sum =3D dd_add(a, b); > + > + /* > + * If we are losing at least two bits of accuracy to denormalizatio= n, > + * then the first lost bit becomes a round bit, and we adjust the > + * lowest bit of sum.hi to make it a sticky bit summarizing all the > + * bits in sum.lo. With the sticky bit adjusted, the hardware will > + * break any ties in the correct direction. > + * > + * If we are losing only one bit to denormalization, however, we mu= st > + * break the ties manually. > + */ > + if (sum.lo !=3D 0) { > + u.e =3D sum.hi; > + bits_lost =3D -u.bits.exp - scale + 1; > + if ((bits_lost !=3D 1) ^ (int)(u.bits.manl & 1)) > + sum.hi =3D nextafterl(sum.hi, INFINITY * sum.lo); > + } > + return (ldexp(sum.hi, scale)); > +} > + > +/* > + * Compute a*b exactly, returning the exact result in a struct dd. We a= ssume > + * that both a and b are normalized, so no underflow or overflow will oc= cur. > + * The current rounding mode must be round-to-nearest. > + */ > +static inline struct dd > +dd_mul(long double a, long double b) > +{ > +#if LDBL_MANT_DIG =3D=3D 64 > + static const long double split =3D 0x1p32L + 1.0; > +#elif LDBL_MANT_DIG =3D=3D 113 > + static const long double split =3D 0x1p57L + 1.0; > +#endif > + struct dd ret; > + long double ha, hb, la, lb, p, q; > + > + p =3D a * split; > + ha =3D a - p; > + ha +=3D p; > + la =3D a - ha; > + > + p =3D b * split; > + hb =3D b - p; > + hb +=3D p; > + lb =3D b - hb; > + > + p =3D ha * hb; > + q =3D ha * lb + la * hb; > + > + ret.hi =3D p + q; > + ret.lo =3D p - ret.hi + q + la * lb; > + return (ret); > +} > + > +/* > + * Fused multiply-add: Compute x * y + z with a single rounding error. > + * > + * We use scaling to avoid overflow/underflow, along with the > + * canonical precision-doubling technique adapted from: > + * > + * Dekker, T. A Floating-Point Technique for Extending the > + * Available Precision. Numer. Math. 18, 224-242 (1971). > + */ > +long double > +fmal(long double x, long double y, long double z) > +{ > + long double xs, ys, zs, adj; > + struct dd xy, r; > + int oround; > + int ex, ey, ez; > + int spread; > + > + /* > + * Handle special cases. The order of operations and the particular > + * return values here are crucial in handling special cases involvi= ng > + * infinities, NaNs, overflows, and signed zeroes correctly. > + */ > + if (x =3D=3D 0.0 || y =3D=3D 0.0) > + return (x * y + z); > + if (z =3D=3D 0.0) > + return (x * y); > + if (!isfinite(x) || !isfinite(y)) > + return (x * y + z); > + if (!isfinite(z)) > + return (z); > + > + xs =3D frexpl(x, &ex); > + ys =3D frexpl(y, &ey); > + zs =3D frexpl(z, &ez); > + oround =3D fegetround(); > + spread =3D ex + ey - ez; > + > + /* > + * If x * y and z are many orders of magnitude apart, the scaling > + * will overflow, so we handle these cases specially. Rounding > + * modes other than FE_TONEAREST are painful. > + */ > + if (spread < -LDBL_MANT_DIG) { > + feraiseexcept(FE_INEXACT); > + if (!isnormal(z)) > + feraiseexcept(FE_UNDERFLOW); > + switch (oround) { > + case FE_TONEAREST: > + return (z); > + case FE_TOWARDZERO: > + if (x > 0.0 ^ y < 0.0 ^ z < 0.0) > + return (z); > + else > + return (nextafterl(z, 0)); > + case FE_DOWNWARD: > + if (x > 0.0 ^ y < 0.0) > + return (z); > + else > + return (nextafterl(z, -INFINITY)); > + default: /* FE_UPWARD */ > + if (x > 0.0 ^ y < 0.0) > + return (nextafterl(z, INFINITY)); > + else > + return (z); > + } > + } > + if (spread <=3D LDBL_MANT_DIG * 2) > + zs =3D ldexpl(zs, -spread); > + else > + zs =3D copysignl(LDBL_MIN, zs); > + > + fesetround(FE_TONEAREST); > + /* work around clang bug 8100 */ > + volatile long double vxs =3D xs; > + > + /* > + * Basic approach for round-to-nearest: > + * > + * (xy.hi, xy.lo) =3D x * y (exact) > + * (r.hi, r.lo) =3D xy.hi + z (exact) > + * adj =3D xy.lo + r.lo (inexact; low bit is stic= ky) > + * result =3D r.hi + adj (correctly rounded) > + */ > + xy =3D dd_mul(vxs, ys); > + r =3D dd_add(xy.hi, zs); > + > + spread =3D ex + ey; > + > + if (r.hi =3D=3D 0.0) { > + /* > + * When the addends cancel to 0, ensure that the result has > + * the correct sign. > + */ > + fesetround(oround); > + volatile long double vzs =3D zs; /* XXX gcc CSE bug workaro= und */ > + return (xy.hi + vzs + ldexpl(xy.lo, spread)); > + } > + > + if (oround !=3D FE_TONEAREST) { > + /* > + * There is no need to worry about double rounding in direc= ted > + * rounding modes. > + */ > + fesetround(oround); > + /* work around clang bug 8100 */ > + volatile long double vrlo =3D r.lo; > + adj =3D vrlo + xy.lo; > + return (ldexpl(r.hi + adj, spread)); > + } > + > + adj =3D add_adjusted(r.lo, xy.lo); > + if (spread + ilogbl(r.hi) > -16383) > + return (ldexpl(r.hi + adj, spread)); > + else > + return (add_and_denormalize(r.hi, adj, spread)); > +} > diff --git a/newlib/libm/ld/s_fmaxl.c b/newlib/libm/ld/s_fmaxl.c > new file mode 100644 > index 000000000..c0d7c8832 > --- /dev/null > +++ b/newlib/libm/ld/s_fmaxl.c > @@ -0,0 +1,57 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2004 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > + > +#include "fpmath.h" > + > +long double > +fmaxl(long double x, long double y) > +{ > + union IEEEl2bits u[2]; > + > + u[0].e =3D x; > + mask_nbit_l(u[0]); > + u[1].e =3D y; > + mask_nbit_l(u[1]); > + > + /* Check for NaNs to avoid raising spurious exceptions. */ > + if (u[0].bits.exp =3D=3D 32767 && (u[0].bits.manh | u[0].bits.manl)= !=3D 0) > + return (y); > + if (u[1].bits.exp =3D=3D 32767 && (u[1].bits.manh | u[1].bits.manl)= !=3D 0) > + return (x); > + > + /* Handle comparisons of signed zeroes. */ > + if (u[0].bits.sign !=3D u[1].bits.sign) > + return (u[0].bits.sign ? y : x); > + > + return (x > y ? x : y); > +} > diff --git a/newlib/libm/ld/s_fminl.c b/newlib/libm/ld/s_fminl.c > new file mode 100644 > index 000000000..97604b38b > --- /dev/null > +++ b/newlib/libm/ld/s_fminl.c > @@ -0,0 +1,57 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2004 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > + > +#include "fpmath.h" > + > +long double > +fminl(long double x, long double y) > +{ > + union IEEEl2bits u[2]; > + > + u[0].e =3D x; > + mask_nbit_l(u[0]); > + u[1].e =3D y; > + mask_nbit_l(u[1]); > + > + /* Check for NaNs to avoid raising spurious exceptions. */ > + if (u[0].bits.exp =3D=3D 32767 && (u[0].bits.manh | u[0].bits.manl)= !=3D 0) > + return (y); > + if (u[1].bits.exp =3D=3D 32767 && (u[1].bits.manh | u[1].bits.manl)= !=3D 0) > + return (x); > + > + /* Handle comparisons of signed zeroes. */ > + if (u[0].bits.sign !=3D u[1].bits.sign) > + return (u[1].bits.sign ? y : x); > + > + return (x < y ? x : y); > +} > diff --git a/newlib/libm/ld/s_frexpl.c b/newlib/libm/ld/s_frexpl.c > new file mode 100644 > index 000000000..66e284fdd > --- /dev/null > +++ b/newlib/libm/ld/s_frexpl.c > @@ -0,0 +1,64 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2004-2005 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + * > + * $FreeBSD$ > + */ > + > +#include > +#include > + > +#include "fpmath.h" > + > +#if LDBL_MAX_EXP !=3D 0x4000 > +#error "Unsupported long double format" > +#endif > + > +long double > +frexpl(long double x, int *ex) > +{ > + union IEEEl2bits u; > + > + u.e =3D x; > + switch (u.bits.exp) { > + case 0: /* 0 or subnormal */ > + if ((u.bits.manl | u.bits.manh) =3D=3D 0) { > + *ex =3D 0; > + } else { > + u.e *=3D 0x1.0p514; > + *ex =3D u.bits.exp - 0x4200; > + u.bits.exp =3D 0x3ffe; > + } > + break; > + case 0x7fff: /* infinity or NaN; value of *ex is unspecified */ > + break; > + default: /* normal */ > + *ex =3D u.bits.exp - 0x3ffe; > + u.bits.exp =3D 0x3ffe; > + break; > + } > + return (u.e); > +} > diff --git a/newlib/libm/ld/s_ilogbl.c b/newlib/libm/ld/s_ilogbl.c > new file mode 100644 > index 000000000..3211f4409 > --- /dev/null > +++ b/newlib/libm/ld/s_ilogbl.c > @@ -0,0 +1,53 @@ > +/* > + * From: @(#)s_ilogb.c 5.1 93/09/24 > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > +#include > +#include > + > +#include "fpmath.h" > + > +int > +ilogbl(long double x) > +{ > + union IEEEl2bits u; > + unsigned long m; > + int b; > + > + u.e =3D x; > + if (u.bits.exp =3D=3D 0) { > + if ((u.bits.manl | u.bits.manh) =3D=3D 0) > + return (FP_ILOGB0); > + /* denormalized */ > + if (u.bits.manh =3D=3D 0) { > + m =3D 1lu << (LDBL_MANL_SIZE - 1); > + for (b =3D LDBL_MANH_SIZE; !(u.bits.manl & m); m >>= =3D 1) > + b++; > + } else { > + m =3D 1lu << (LDBL_MANH_SIZE - 1); > + for (b =3D 0; !(u.bits.manh & m); m >>=3D 1) > + b++; > + } > +#ifdef LDBL_IMPLICIT_NBIT > + b++; > +#endif > + return (LDBL_MIN_EXP - b - 1); > + } else if (u.bits.exp < (LDBL_MAX_EXP << 1) - 1) > + return (u.bits.exp - LDBL_MAX_EXP + 1); > + else if (u.bits.manl !=3D 0 || u.bits.manh !=3D 0) > + return (FP_ILOGBNAN); > + else > + return (INT_MAX); > +} > diff --git a/newlib/libm/ld/s_llrintl.c b/newlib/libm/ld/s_llrintl.c > new file mode 100644 > index 000000000..6ef83759c > --- /dev/null > +++ b/newlib/libm/ld/s_llrintl.c > @@ -0,0 +1,9 @@ > +#include > +__FBSDID("$FreeBSD$"); > + > +#define type long double > +#define roundit rintl > +#define dtype long long > +#define fn llrintl > + > +#include "s_lrint.c" > diff --git a/newlib/libm/ld/s_llroundl.c b/newlib/libm/ld/s_llroundl.c > new file mode 100644 > index 000000000..02c44eb4b > --- /dev/null > +++ b/newlib/libm/ld/s_llroundl.c > @@ -0,0 +1,11 @@ > +#include > +__FBSDID("$FreeBSD$"); > + > +#define type long double > +#define roundit roundl > +#define dtype long long > +#define DTYPE_MIN LLONG_MIN > +#define DTYPE_MAX LLONG_MAX > +#define fn llroundl > + > +#include "s_lround.c" > diff --git a/newlib/libm/ld/s_logbl.c b/newlib/libm/ld/s_logbl.c > new file mode 100644 > index 000000000..ee1a91fd8 > --- /dev/null > +++ b/newlib/libm/ld/s_logbl.c > @@ -0,0 +1,54 @@ > +/* > + * From: @(#)s_ilogb.c 5.1 93/09/24 > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > +#include > +#include > + > +#include "fpmath.h" > + > +long double > +logbl(long double x) > +{ > + union IEEEl2bits u; > + unsigned long m; > + int b; > + > + u.e =3D x; > + if (u.bits.exp =3D=3D 0) { > + if ((u.bits.manl | u.bits.manh) =3D=3D 0) { /* x =3D=3D 0 *= / > + u.bits.sign =3D 1; > + return (1.0L / u.e); > + } > + /* denormalized */ > + if (u.bits.manh =3D=3D 0) { > + m =3D 1lu << (LDBL_MANL_SIZE - 1); > + for (b =3D LDBL_MANH_SIZE; !(u.bits.manl & m); m >>= =3D 1) > + b++; > + } else { > + m =3D 1lu << (LDBL_MANH_SIZE - 1); > + for (b =3D 0; !(u.bits.manh & m); m >>=3D 1) > + b++; > + } > +#ifdef LDBL_IMPLICIT_NBIT > + b++; > +#endif > + return ((long double)(LDBL_MIN_EXP - b - 1)); > + } > + if (u.bits.exp < (LDBL_MAX_EXP << 1) - 1) /* normal */ > + return ((long double)(u.bits.exp - LDBL_MAX_EXP + 1)); > + else /* +/- inf or nan *= / > + return (x * x); > +} > diff --git a/newlib/libm/ld/s_lrint.c b/newlib/libm/ld/s_lrint.c > new file mode 100644 > index 000000000..ad9b978fa > --- /dev/null > +++ b/newlib/libm/ld/s_lrint.c > @@ -0,0 +1,60 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2005 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +#include > +#include > +#include > + > +#ifndef type > +__FBSDID("$FreeBSD$"); > +#define type double > +#define roundit rint > +#define dtype long > +#define fn lrint > +#endif > + > +/* > + * C99 says we should not raise a spurious inexact exception when an > + * invalid exception is raised. Unfortunately, the set of inputs > + * that overflows depends on the rounding mode when 'dtype' has more > + * significant bits than 'type'. Hence, we bend over backwards for the > + * sake of correctness; an MD implementation could be more efficient. > + */ > +dtype > +fn(type x) > +{ > + fenv_t env; > + dtype d; > + > + feholdexcept(&env); > + d =3D (dtype)roundit(x); > + if (fetestexcept(FE_INVALID)) > + feclearexcept(FE_INEXACT); > + feupdateenv(&env); > + return (d); > +} > diff --git a/newlib/libm/ld/s_lrintl.c b/newlib/libm/ld/s_lrintl.c > new file mode 100644 > index 000000000..497b442f3 > --- /dev/null > +++ b/newlib/libm/ld/s_lrintl.c > @@ -0,0 +1,9 @@ > +#include > +__FBSDID("$FreeBSD$"); > + > +#define type long double > +#define roundit rintl > +#define dtype long > +#define fn lrintl > + > +#include "s_lrint.c" > diff --git a/newlib/libm/ld/s_lround.c b/newlib/libm/ld/s_lround.c > new file mode 100644 > index 000000000..1dd8e697f > --- /dev/null > +++ b/newlib/libm/ld/s_lround.c > @@ -0,0 +1,70 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2005 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +#include > +#include > +#include > +#include > + > +#ifndef type > +__FBSDID("$FreeBSD$"); > +#define type double > +#define roundit round > +#define dtype long > +#define DTYPE_MIN LONG_MIN > +#define DTYPE_MAX LONG_MAX > +#define fn lround > +#endif > + > +/* > + * If type has more precision than dtype, the endpoints dtype_(min|max) = are > + * of the form xxx.5; they are "out of range" because lround() rounds aw= ay > + * from 0. On the other hand, if type has less precision than dtype, th= en > + * all values that are out of range are integral, so we might as well as= sume > + * that everything is in range. At compile time, INRANGE(x) should redu= ce to > + * two floating-point comparisons in the former case, or TRUE otherwise. > + */ > +static const type type_min =3D (type)DTYPE_MIN; > +static const type type_max =3D (type)DTYPE_MAX; > +static const type dtype_min =3D (type)DTYPE_MIN - 0.5; > +static const type dtype_max =3D (type)DTYPE_MAX + 0.5; > +#define INRANGE(x) (dtype_max - type_max !=3D 0.5 || \ > + ((x) > dtype_min && (x) < dtype_max)) > + > +dtype > +fn(type x) > +{ > + > + if (INRANGE(x)) { > + x =3D roundit(x); > + return ((dtype)x); > + } else { > + feraiseexcept(FE_INVALID); > + return (DTYPE_MAX); > + } > +} > diff --git a/newlib/libm/ld/s_lroundl.c b/newlib/libm/ld/s_lroundl.c > new file mode 100644 > index 000000000..e410827e2 > --- /dev/null > +++ b/newlib/libm/ld/s_lroundl.c > @@ -0,0 +1,11 @@ > +#include > +__FBSDID("$FreeBSD$"); > + > +#define type long double > +#define roundit roundl > +#define dtype long > +#define DTYPE_MIN LONG_MIN > +#define DTYPE_MAX LONG_MAX > +#define fn lroundl > + > +#include "s_lround.c" > diff --git a/newlib/libm/ld/s_modfl.c b/newlib/libm/ld/s_modfl.c > new file mode 100644 > index 000000000..2d83bbe33 > --- /dev/null > +++ b/newlib/libm/ld/s_modfl.c > @@ -0,0 +1,103 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2007 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + * > + * Derived from s_modf.c, which has the following Copyright: > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * > + * $FreeBSD$ > + */ > + > +#include > +#include > +#include > + > +#include "fpmath.h" > + > +#if LDBL_MANL_SIZE > 32 > +#define MASK ((uint64_t)-1) > +#else > +#define MASK ((uint32_t)-1) > +#endif > +/* Return the last n bits of a word, representing the fractional part. *= / > +#define GETFRAC(bits, n) ((bits) & ~(MASK << (n))) > +/* The number of fraction bits in manh, not counting the integer bit */ > +#define HIBITS (LDBL_MANT_DIG - LDBL_MANL_SIZE) > + > +static const long double zero[] =3D { 0.0L, -0.0L }; > + > +long double > +modfl(long double x, long double *iptr) > +{ > + union IEEEl2bits ux; > + int e; > + > + ux.e =3D x; > + e =3D ux.bits.exp - LDBL_MAX_EXP + 1; > + if (e < HIBITS) { /* Integer part is in manh.= */ > + if (e < 0) { /* |x|<1 */ > + *iptr =3D zero[ux.bits.sign]; > + return (x); > + } else { > + if ((GETFRAC(ux.bits.manh, HIBITS - 1 - e) | > + ux.bits.manl) =3D=3D 0) { /* X is an inte= ger. */ > + *iptr =3D x; > + return (zero[ux.bits.sign]); > + } else { > + /* Clear all but the top e+1 bits. */ > + ux.bits.manh >>=3D HIBITS - 1 - e; > + ux.bits.manh <<=3D HIBITS - 1 - e; > + ux.bits.manl =3D 0; > + *iptr =3D ux.e; > + return (x - ux.e); > + } > + } > + } else if (e >=3D LDBL_MANT_DIG - 1) { /* x has no fraction part= . */ > + *iptr =3D x; > + if (x !=3D x) /* Handle NaNs. */ > + return (x); > + return (zero[ux.bits.sign]); > + } else { /* Fraction part is in manl= . */ > + if (GETFRAC(ux.bits.manl, LDBL_MANT_DIG - 1 - e) =3D=3D 0) = { > + /* x is integral. */ > + *iptr =3D x; > + return (zero[ux.bits.sign]); > + } else { > + /* Clear all but the top e+1 bits. */ > + ux.bits.manl >>=3D LDBL_MANT_DIG - 1 - e; > + ux.bits.manl <<=3D LDBL_MANT_DIG - 1 - e; > + *iptr =3D ux.e; > + return (x - ux.e); > + } > + } > +} > diff --git a/newlib/libm/ld/s_nearbyint.c b/newlib/libm/ld/s_nearbyint.c > new file mode 100644 > index 000000000..796dbaf98 > --- /dev/null > +++ b/newlib/libm/ld/s_nearbyint.c > @@ -0,0 +1,61 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2004 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > +#include > + > +/* > + * We save and restore the floating-point environment to avoid raising > + * an inexact exception. We can get away with using fesetenv() > + * instead of feclearexcept()/feupdateenv() to restore the environment > + * because the only exception defined for rint() is overflow, and > + * rounding can't overflow as long as emax >=3D p. > + * > + * The volatile keyword is needed below because clang incorrectly assume= s > + * that rint won't raise any floating-point exceptions. Declaring ret vo= latile > + * is sufficient to trick the compiler into doing the right thing. > + */ > +#define DECL(type, fn, rint) \ > +type \ > +fn(type x) \ > +{ \ > + volatile type ret; \ > + fenv_t env; \ > + \ > + fegetenv(&env); \ > + ret =3D rint(x); \ > + fesetenv(&env); \ > + return (ret); \ > +} > + > +DECL(double, nearbyint, rint) > +DECL(float, nearbyintf, rintf) > +DECL(long double, nearbyintl, rintl) > diff --git a/newlib/libm/ld/s_nextafterl.c b/newlib/libm/ld/s_nextafterl.= c > new file mode 100644 > index 000000000..9c61a436a > --- /dev/null > +++ b/newlib/libm/ld/s_nextafterl.c > @@ -0,0 +1,80 @@ > +/* @(#)s_nextafter.c 5.1 93/09/24 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* IEEE functions > + * nextafter(x,y) > + * return the next machine floating-point number of x in the > + * direction toward y. > + * Special cases: > + */ > + > +#include > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +#if LDBL_MAX_EXP !=3D 0x4000 > +#error "Unsupported long double format" > +#endif > + > +long double > +nextafterl(long double x, long double y) > +{ > + volatile long double t; > + union IEEEl2bits ux, uy; > + > + ux.e =3D x; > + uy.e =3D y; > + > + if ((ux.bits.exp =3D=3D 0x7fff && > + ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl) !=3D 0) || > + (uy.bits.exp =3D=3D 0x7fff && > + ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) !=3D 0)) > + return x+y; /* x or y is nan */ > + if(x=3D=3Dy) return y; /* x=3Dy, return y */ > + if(x=3D=3D0.0) { > + ux.bits.manh =3D 0; /* return +-minsubnormal = */ > + ux.bits.manl =3D 1; > + ux.bits.sign =3D uy.bits.sign; > + t =3D ux.e*ux.e; > + if(t=3D=3Dux.e) return t; else return ux.e; /* raise underflow = flag */ > + } > + if(x>0.0 ^ x + if(ux.bits.manl=3D=3D0) { > + if ((ux.bits.manh&~LDBL_NBIT)=3D=3D0) > + ux.bits.exp -=3D 1; > + ux.bits.manh =3D (ux.bits.manh - 1) | (ux.bits.manh & LDBL_= NBIT); > + } > + ux.bits.manl -=3D 1; > + } else { /* x +=3D ulp */ > + ux.bits.manl +=3D 1; > + if(ux.bits.manl=3D=3D0) { > + ux.bits.manh =3D (ux.bits.manh + 1) | (ux.bits.manh & LDBL_= NBIT); > + if ((ux.bits.manh&~LDBL_NBIT)=3D=3D0) > + ux.bits.exp +=3D 1; > + } > + } > + if(ux.bits.exp=3D=3D0x7fff) return x+x; /* overflow */ > + if(ux.bits.exp=3D=3D0) { /* underflow */ > + mask_nbit_l(ux); > + t =3D ux.e * ux.e; > + if(t!=3Dux.e) /* raise underflow flag */ > + return ux.e; > + } > + return ux.e; > +} > + > +__strong_reference(nextafterl, nexttowardl); > diff --git a/newlib/libm/ld/s_nexttoward.c b/newlib/libm/ld/s_nexttoward.= c > new file mode 100644 > index 000000000..b2a50d313 > --- /dev/null > +++ b/newlib/libm/ld/s_nexttoward.c > @@ -0,0 +1,72 @@ > +/* @(#)s_nextafter.c 5.1 93/09/24 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * We assume that a long double has a 15-bit exponent. On systems > + * where long double is the same as double, nexttoward() is an alias > + * for nextafter(), so we don't use this routine. > + */ > + > +#include > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +#if LDBL_MAX_EXP !=3D 0x4000 > +#error "Unsupported long double format" > +#endif > + > +double > +nexttoward(double x, long double y) > +{ > + union IEEEl2bits uy; > + volatile double t; > + int32_t hx,ix; > + u_int32_t lx; > + > + EXTRACT_WORDS(hx,lx,x); > + ix =3D hx&0x7fffffff; /* |x| */ > + uy.e =3D y; > + > + if(((ix>=3D0x7ff00000)&&((ix-0x7ff00000)|lx)!=3D0) || > + (uy.bits.exp =3D=3D 0x7fff && > + ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) !=3D 0)) > + return x+y; /* x or y is nan */ > + if(x=3D=3Dy) return (double)y; /* x=3Dy, return y */ > + if(x=3D=3D0.0) { > + INSERT_WORDS(x,uy.bits.sign<<31,1); /* return +-minsubnormal */ > + t =3D x*x; > + if(t=3D=3Dx) return t; else return x; /* raise underflow flag= */ > + } > + if(hx>0.0 ^ x < y) { /* x -=3D ulp */ > + if(lx=3D=3D0) hx -=3D 1; > + lx -=3D 1; > + } else { /* x +=3D ulp */ > + lx +=3D 1; > + if(lx=3D=3D0) hx +=3D 1; > + } > + ix =3D hx&0x7ff00000; > + if(ix>=3D0x7ff00000) return x+x; /* overflow */ > + if(ix<0x00100000) { /* underflow */ > + t =3D x*x; > + if(t!=3Dx) { /* raise underflow flag */ > + INSERT_WORDS(x,hx,lx); > + return x; > + } > + } > + INSERT_WORDS(x,hx,lx); > + return x; > +} > diff --git a/newlib/libm/ld/s_nexttowardf.c b/newlib/libm/ld/s_nexttoward= f.c > new file mode 100644 > index 000000000..9ddfff961 > --- /dev/null > +++ b/newlib/libm/ld/s_nexttowardf.c > @@ -0,0 +1,59 @@ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +#define LDBL_INFNAN_EXP (LDBL_MAX_EXP * 2 - 1) > + > +float > +nexttowardf(float x, long double y) > +{ > + union IEEEl2bits uy; > + volatile float t; > + int32_t hx,ix; > + > + GET_FLOAT_WORD(hx,x); > + ix =3D hx&0x7fffffff; /* |x| */ > + uy.e =3D y; > + > + if((ix>0x7f800000) || > + (uy.bits.exp =3D=3D LDBL_INFNAN_EXP && > + ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) !=3D 0)) > + return x+y; /* x or y is nan */ > + if(x=3D=3Dy) return (float)y; /* x=3Dy, return y */ > + if(ix=3D=3D0) { /* x =3D=3D 0 */ > + SET_FLOAT_WORD(x,(uy.bits.sign<<31)|1);/* return +-minsubnormal= */ > + t =3D x*x; > + if(t=3D=3Dx) return t; else return x; /* raise underflow flag= */ > + } > + if(hx>=3D0 ^ x < y) /* x -=3D ulp */ > + hx -=3D 1; > + else /* x +=3D ulp */ > + hx +=3D 1; > + ix =3D hx&0x7f800000; > + if(ix>=3D0x7f800000) return x+x; /* overflow */ > + if(ix<0x00800000) { /* underflow */ > + t =3D x*x; > + if(t!=3Dx) { /* raise underflow flag */ > + SET_FLOAT_WORD(x,hx); > + return x; > + } > + } > + SET_FLOAT_WORD(x,hx); > + return x; > +} > diff --git a/newlib/libm/ld/s_remquol.c b/newlib/libm/ld/s_remquol.c > new file mode 100644 > index 000000000..a9f5813d0 > --- /dev/null > +++ b/newlib/libm/ld/s_remquol.c > @@ -0,0 +1,173 @@ > +/* @(#)e_fmod.c 1.3 95/01/18 */ > +/*- > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > +#include > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +#define BIAS (LDBL_MAX_EXP - 1) > + > +#if LDBL_MANL_SIZE > 32 > +typedef uint64_t manl_t; > +#else > +typedef uint32_t manl_t; > +#endif > + > +#if LDBL_MANH_SIZE > 32 > +typedef uint64_t manh_t; > +#else > +typedef uint32_t manh_t; > +#endif > + > +/* > + * These macros add and remove an explicit integer bit in front of the > + * fractional mantissa, if the architecture doesn't have such a bit by > + * default already. > + */ > +#ifdef LDBL_IMPLICIT_NBIT > +#define SET_NBIT(hx) ((hx) | (1ULL << LDBL_MANH_SIZE)) > +#define HFRAC_BITS LDBL_MANH_SIZE > +#else > +#define SET_NBIT(hx) (hx) > +#define HFRAC_BITS (LDBL_MANH_SIZE - 1) > +#endif > + > +#define MANL_SHIFT (LDBL_MANL_SIZE - 1) > + > +static const long double Zero[] =3D {0.0L, -0.0L}; > + > +/* > + * Return the IEEE remainder and set *quo to the last n bits of the > + * quotient, rounded to the nearest integer. We choose n=3D31 because > + * we wind up computing all the integer bits of the quotient anyway as > + * a side-effect of computing the remainder by the shift and subtract > + * method. In practice, this is far more bits than are needed to use > + * remquo in reduction algorithms. > + * > + * Assumptions: > + * - The low part of the mantissa fits in a manl_t exactly. > + * - The high part of the mantissa fits in an int64_t with enough room > + * for an explicit integer bit in front of the fractional bits. > + */ > +long double > +remquol(long double x, long double y, int *quo) > +{ > + union IEEEl2bits ux, uy; > + int64_t hx,hz; /* We need a carry bit even if LDBL_MANH_SIZE is 32= . */ > + manh_t hy; > + manl_t lx,ly,lz; > + int ix,iy,n,q,sx,sxy; > + > + ux.e =3D x; > + uy.e =3D y; > + sx =3D ux.bits.sign; > + sxy =3D sx ^ uy.bits.sign; > + ux.bits.sign =3D 0; /* |x| */ > + uy.bits.sign =3D 0; /* |y| */ > + > + /* purge off exception values */ > + if((uy.bits.exp|uy.bits.manh|uy.bits.manl)=3D=3D0 || /* y=3D0 */ > + (ux.bits.exp =3D=3D BIAS + LDBL_MAX_EXP) || /* or x not fi= nite */ > + (uy.bits.exp =3D=3D BIAS + LDBL_MAX_EXP && > + ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl)!=3D0)) /* or y is NaN = */ > + return nan_mix_op(x, y, *)/nan_mix_op(x, y, *); > + if(ux.bits.exp<=3Duy.bits.exp) { > + if((ux.bits.exp + (ux.bits.manh<=3Duy.bits.manh && > + (ux.bits.manh + ux.bits.manl + q =3D 0; > + goto fixup; /* |x|<|y| return x or x-y */ > + } > + if(ux.bits.manh=3D=3Duy.bits.manh && ux.bits.manl=3D=3Duy.bits.= manl) { > + *quo =3D (sxy ? -1 : 1); > + return Zero[sx]; /* |x|=3D|y| return x*0*/ > + } > + } > + > + /* determine ix =3D ilogb(x) */ > + if(ux.bits.exp =3D=3D 0) { /* subnormal x */ > + ux.e *=3D 0x1.0p512; > + ix =3D ux.bits.exp - (BIAS + 512); > + } else { > + ix =3D ux.bits.exp - BIAS; > + } > + > + /* determine iy =3D ilogb(y) */ > + if(uy.bits.exp =3D=3D 0) { /* subnormal y */ > + uy.e *=3D 0x1.0p512; > + iy =3D uy.bits.exp - (BIAS + 512); > + } else { > + iy =3D uy.bits.exp - BIAS; > + } > + > + /* set up {hx,lx}, {hy,ly} and align y to x */ > + hx =3D SET_NBIT(ux.bits.manh); > + hy =3D SET_NBIT(uy.bits.manh); > + lx =3D ux.bits.manl; > + ly =3D uy.bits.manl; > + > + /* fix point fmod */ > + n =3D ix - iy; > + q =3D 0; > + while(n--) { > + hz=3Dhx-hy;lz=3Dlx-ly; if(lx + if(hz<0){hx =3D hx+hx+(lx>>MANL_SHIFT); lx =3D lx+lx;} > + else {hx =3D hz+hz+(lz>>MANL_SHIFT); lx =3D lz+lz; q++;} > + q <<=3D 1; > + } > + hz=3Dhx-hy;lz=3Dlx-ly; if(lx + if(hz>=3D0) {hx=3Dhz;lx=3Dlz;q++;} > + > + /* convert back to floating value and restore the sign */ > + if((hx|lx)=3D=3D0) { /* return sign(x)*0 */ > + q &=3D 0x7fffffff; > + *quo =3D (sxy ? -q : q); > + return Zero[sx]; > + } > + while(hx<(1ULL< + hx =3D hx+hx+(lx>>MANL_SHIFT); lx =3D lx+lx; > + iy -=3D 1; > + } > + ux.bits.manh =3D hx; /* The integer bit is truncated here if needed= . */ > + ux.bits.manl =3D lx; > + if (iy < LDBL_MIN_EXP) { > + ux.bits.exp =3D iy + (BIAS + 512); > + ux.e *=3D 0x1p-512; > + } else { > + ux.bits.exp =3D iy + BIAS; > + } > +fixup: > + x =3D ux.e; /* |x| */ > + y =3D fabsl(y); > + if (y < LDBL_MIN * 2) { > + if (x+x>y || (x+x=3D=3Dy && (q & 1))) { > + q++; > + x-=3Dy; > + } > + } else if (x>0.5*y || (x=3D=3D0.5*y && (q & 1))) { > + q++; > + x-=3Dy; > + } > + ux.e =3D x; > + ux.bits.sign ^=3D sx; > + x =3D ux.e; > + q &=3D 0x7fffffff; > + *quo =3D (sxy ? -q : q); > + return x; > +} > diff --git a/newlib/libm/ld/s_rintl.c b/newlib/libm/ld/s_rintl.c > new file mode 100644 > index 000000000..1e9824d83 > --- /dev/null > +++ b/newlib/libm/ld/s_rintl.c > @@ -0,0 +1,92 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2008 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > +#include > + > +#include "fpmath.h" > + > +#if LDBL_MAX_EXP !=3D 0x4000 > +/* We also require the usual bias, min exp and expsign packing. */ > +#error "Unsupported long double format" > +#endif > + > +#define BIAS (LDBL_MAX_EXP - 1) > + > +static const float > +shift[2] =3D { > +#if LDBL_MANT_DIG =3D=3D 64 > + 0x1.0p63, -0x1.0p63 > +#elif LDBL_MANT_DIG =3D=3D 113 > + 0x1.0p112, -0x1.0p112 > +#else > +#error "Unsupported long double format" > +#endif > +}; > +static const float zero[2] =3D { 0.0, -0.0 }; > + > +long double > +rintl(long double x) > +{ > + union IEEEl2bits u; > + uint32_t expsign; > + int ex, sign; > + > + u.e =3D x; > + expsign =3D u.xbits.expsign; > + ex =3D expsign & 0x7fff; > + > + if (ex >=3D BIAS + LDBL_MANT_DIG - 1) { > + if (ex =3D=3D BIAS + LDBL_MAX_EXP) > + return (x + x); /* Inf, NaN, or unsupported format = */ > + return (x); /* finite and already an integer */ > + } > + sign =3D expsign >> 15; > + > + /* > + * The following code assumes that intermediate results are > + * evaluated in long double precision. If they are evaluated in > + * greater precision, double rounding may occur, and if they are > + * evaluated in less precision (as on i386), results will be > + * wildly incorrect. > + */ > + x +=3D shift[sign]; > + x -=3D shift[sign]; > + > + /* > + * If the result is +-0, then it must have the same sign as x, but > + * the above calculation doesn't always give this. Fix up the sign= . > + */ > + if (ex < BIAS && x =3D=3D 0.0L) > + return (zero[sign]); > + > + return (x); > +} > diff --git a/newlib/libm/ld/s_roundl.c b/newlib/libm/ld/s_roundl.c > new file mode 100644 > index 000000000..8d1c02a7f > --- /dev/null > +++ b/newlib/libm/ld/s_roundl.c > @@ -0,0 +1,64 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2003, Steven G. Kargl > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice unmodified, this list of conditions, and the following > + * disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > +#ifdef __i386__ > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +long double > +roundl(long double x) > +{ > + long double t; > + uint16_t hx; > + > + GET_LDBL_EXPSIGN(hx, x); > + if ((hx & 0x7fff) =3D=3D 0x7fff) > + return (x + x); > + > + ENTERI(); > + > + if (!(hx & 0x8000)) { > + t =3D floorl(x); > + if (t - x <=3D -0.5L) > + t +=3D 1; > + RETURNI(t); > + } else { > + t =3D floorl(-x); > + if (t + x <=3D -0.5L) > + t +=3D 1; > + RETURNI(-t); > + } > +} > diff --git a/newlib/libm/ld/s_scalbln.c b/newlib/libm/ld/s_scalbln.c > new file mode 100644 > index 000000000..c27420c92 > --- /dev/null > +++ b/newlib/libm/ld/s_scalbln.c > @@ -0,0 +1,56 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2004 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > + > +#define NMAX 65536 > +#define NMIN -65536 > + > +double > +scalbln(double x, long n) > +{ > + > + return (scalbn(x, (n > NMAX) ? NMAX : (n < NMIN) ? NMIN : (int)n)); > +} > + > +float > +scalblnf(float x, long n) > +{ > + > + return (scalbnf(x, (n > NMAX) ? NMAX : (n < NMIN) ? NMIN : (int)n))= ; > +} > + > +long double > +scalblnl(long double x, long n) > +{ > + > + return (scalbnl(x, (n > NMAX) ? NMAX : (n < NMIN) ? NMIN : (int)n))= ; > +} > diff --git a/newlib/libm/ld/s_scalbnl.c b/newlib/libm/ld/s_scalbnl.c > new file mode 100644 > index 000000000..6044c1b1d > --- /dev/null > +++ b/newlib/libm/ld/s_scalbnl.c > @@ -0,0 +1,49 @@ > +/* > + * Copyright (c) 2005-2020 Rich Felker, et al. > + * > + * SPDX-License-Identifier: MIT > + * > + * Please see https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT > + * for all contributors to musl. > + */ > +#include > +#include > +#include "math_private.h" > +#include "fpmath.h" > +/* > + * scalbnl (long double x, int n) > + * scalbnl(x,n) returns x* 2**n computed by exponent > + * manipulation rather than by actually performing an > + * exponentiation or a multiplication. > + */ > +#if (LDBL_MANT_DIG =3D=3D 64 || LDBL_MANT_DIG =3D=3D 113) && LDBL_MAX_EX= P =3D=3D 16384 > +long double scalbnl(long double x, int n) > +{ > + union IEEEl2bits u; > + > + if (n > 16383) { > + x *=3D 0x1p16383L; > + n -=3D 16383; > + if (n > 16383) { > + x *=3D 0x1p16383L; > + n -=3D 16383; > + if (n > 16383) > + n =3D 16383; > + } > + } else if (n < -16382) { > + x *=3D 0x1p-16382L * 0x1p113L; > + n +=3D 16382 - 113; > + if (n < -16382) { > + x *=3D 0x1p-16382L * 0x1p113L; > + n +=3D 16382 - 113; > + if (n < -16382) > + n =3D -16382; > + } > + } > + u.e =3D 1.0; > + u.xbits.expsign =3D 0x3fff + n; > + return x * u.e; > +} > +__strong_reference(scalbnl, ldexpl); > +#endif > + > diff --git a/newlib/libm/ld/s_sinl.c b/newlib/libm/ld/s_sinl.c > new file mode 100644 > index 000000000..f1ef84c8c > --- /dev/null > +++ b/newlib/libm/ld/s_sinl.c > @@ -0,0 +1,95 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2007 Steven G. Kargl > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice unmodified, this list of conditions, and the following > + * disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > +#ifdef __i386__ > +#include > +#endif > + > +#include "math.h" > +#include "math_private.h" > +#if LDBL_MANT_DIG =3D=3D 64 > +#include "../ld80/e_rem_pio2l.h" > +#elif LDBL_MANT_DIG =3D=3D 113 > +#include "../ld128/e_rem_pio2l.h" > +#else > +#error "Unsupported long double format" > +#endif > + > +long double > +sinl(long double x) > +{ > + union IEEEl2bits z; > + int e0, s; > + long double y[2]; > + long double hi, lo; > + > + z.e =3D x; > + s =3D z.bits.sign; > + z.bits.sign =3D 0; > + > + /* If x =3D +-0 or x is a subnormal number, then sin(x) =3D x */ > + if (z.bits.exp =3D=3D 0) > + return (x); > + > + /* If x =3D NaN or Inf, then sin(x) =3D NaN. */ > + if (z.bits.exp =3D=3D 32767) > + return ((x - x) / (x - x)); > + > + ENTERI(); > + > + /* Optimize the case where x is already within range. */ > + if (z.e < M_PI_4) { > + hi =3D __kernel_sinl(z.e, 0, 0); > + RETURNI(s ? -hi : hi); > + } > + > + e0 =3D __ieee754_rem_pio2l(x, y); > + hi =3D y[0]; > + lo =3D y[1]; > + > + switch (e0 & 3) { > + case 0: > + hi =3D __kernel_sinl(hi, lo, 1); > + break; > + case 1: > + hi =3D __kernel_cosl(hi, lo); > + break; > + case 2: > + hi =3D - __kernel_sinl(hi, lo, 1); > + break; > + case 3: > + hi =3D - __kernel_cosl(hi, lo); > + break; > + } > + > + RETURNI(hi); > +} > diff --git a/newlib/libm/ld/s_tanhl.c b/newlib/libm/ld/s_tanhl.c > new file mode 100644 > index 000000000..b7531866d > --- /dev/null > +++ b/newlib/libm/ld/s_tanhl.c > @@ -0,0 +1,174 @@ > +/* from: FreeBSD: head/lib/msun/src/s_tanhl.c XXX */ > + > +/* @(#)s_tanh.c 5.1 93/09/24 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See s_tanh.c for complete comments. > + * > + * Converted to long double by Bruce D. Evans. > + */ > + > +#include > +#ifdef __i386__ > +#include > +#endif > + > +#include "math.h" > +#include "math_private.h" > +#include "fpmath.h" > +#include "k_expl.h" > + > +#if LDBL_MAX_EXP !=3D 0x4000 > +/* We also require the usual expsign encoding. */ > +#error "Unsupported long double format" > +#endif > + > +#define BIAS (LDBL_MAX_EXP - 1) > + > +static const volatile double tiny =3D 1.0e-300; > +static const double one =3D 1.0; > +#if LDBL_MANT_DIG =3D=3D 64 > +/* > + * Domain [-0.25, 0.25], range ~[-1.6304e-22, 1.6304e-22]: > + * |tanh(x)/x - t(x)| < 2**-72.3 > + */ > +static const union IEEEl2bits > +T3u =3D LD80C(0xaaaaaaaaaaaaaa9f, -2, -3.33333333333333333017e-1L); > +#define T3 T3u.e > +static const double > +T5 =3D 1.3333333333333314e-1, /* 0x1111111111110a.0p-5= 5 */ > +T7 =3D -5.3968253968210485e-2, /* -0x1ba1ba1ba1a1a1.0p-5= 7 */ > +T9 =3D 2.1869488531393817e-2, /* 0x1664f488172022.0p-5= 8 */ > +T11 =3D -8.8632352345964591e-3, /* -0x1226e34bc138d5.0p-5= 9 */ > +T13 =3D 3.5921169709993771e-3, /* 0x1d6d371d3e400f.0p-6= 1 */ > +T15 =3D -1.4555786415756001e-3, /* -0x17d923aa63814d.0p-6= 2 */ > +T17 =3D 5.8645267876296793e-4, /* 0x13378589b85aa7.0p-6= 3 */ > +T19 =3D -2.1121033571392224e-4; /* -0x1baf0af80c4090.0p-6= 5 */ > +#elif LDBL_MANT_DIG =3D=3D 113 > +/* > + * Domain [-0.25, 0.25], range ~[-2.4211e-37, 2.4211e-37]: > + * |tanh(x)/x - t(x)| < 2**121.6 > + */ > +static const long double > +T3 =3D -3.33333333333333333333333333333332980e-1L, /* -0x15555555555= 55555555555555554e.0p-114L */ > +T5 =3D 1.33333333333333333333333333332707260e-1L, /* 0x11111111111= 11111111111110ab7b.0p-115L */ > +T7 =3D -5.39682539682539682539682535723482314e-2L, /* -0x1ba1ba1ba1b= a1ba1ba1ba17b5fc98.0p-117L */ > +T9 =3D 2.18694885361552028218693591149061717e-2L, /* 0x1664f4882c1= 0f9f32d6b1a12a25e5.0p-118L */ > +T11 =3D -8.86323552990219656883762347736381851e-3L, /* -0x1226e355e6c= 23c8f5a5a0f386cb4d.0p-119L */ > +T13 =3D 3.59212803657248101358314398220822722e-3L, /* 0x1d6d3d0e157= ddfb403ad3637442c6.0p-121L */ > +T15 =3D -1.45583438705131796512568010348874662e-3L; /* -0x17da36452b7= 5e150c44cc34253b34.0p-122L */ > +static const double > +T17 =3D 5.9002744094556621e-4, /* 0x1355824803668e.0p-6= 3 */ > +T19 =3D -2.3912911424260516e-4, /* -0x1f57d7734c8dde.0p-6= 5 */ > +T21 =3D 9.6915379535512898e-5, /* 0x1967e18ad6a6ca.0p-6= 6 */ > +T23 =3D -3.9278322983156353e-5, /* -0x1497d8e6b75729.0p-6= 7 */ > +T25 =3D 1.5918887220143869e-5, /* 0x10b1319998cafa.0p-6= 8 */ > +T27 =3D -6.4514295231630956e-6, /* -0x1b0f2b71b218eb.0p-7= 0 */ > +T29 =3D 2.6120754043964365e-6, /* 0x15e963a3cf3a39.0p-7= 1 */ > +T31 =3D -1.0407567231003314e-6, /* -0x1176041e656869.0p-7= 2 */ > +T33 =3D 3.4744117554063574e-7; /* 0x1750fe732cab9c.0p-7= 4 */ > +#endif /* LDBL_MANT_DIG =3D=3D 64 */ > + > +static inline long double > +divl(long double a, long double b, long double c, long double d, > + long double e, long double f) > +{ > + long double inv, r; > + float fr, fw; > + > + _2sumF(a, c); > + b =3D b + c; > + _2sumF(d, f); > + e =3D e + f; > + > + inv =3D 1 / (d + e); > + > + r =3D (a + b) * inv; > + fr =3D r; > + r =3D fr; > + > + fw =3D d + e; > + e =3D d - fw + e; > + d =3D fw; > + > + r =3D r + (a - d * r + b - e * r) * inv; > + > + return r; > +} > + > +long double > +tanhl(long double x) > +{ > + long double hi,lo,s,x2,x4,z; > +#if LDBL_MANT_DIG =3D=3D 113 > + double dx2; > +#endif > + int16_t jx,ix; > + > + GET_LDBL_EXPSIGN(jx,x); > + ix =3D jx&0x7fff; > + > + /* x is INF or NaN */ > + if(ix>=3D0x7fff) { > + if (jx>=3D0) return one/x+one; /* tanh(+-inf)=3D+-1 */ > + else return one/x-one; /* tanh(NaN) =3D NaN */ > + } > + > + ENTERI(); > + > + /* |x| < 40 */ > + if (ix < 0x4004 || fabsl(x) < 40) { /* |x|<40 */ > + if (__predict_false(ix + /* tanh(+-0) =3D +0; tanh(tiny) =3D tiny(-+) with inexact: = */ > + return (x =3D=3D 0 ? x : (0x1p200 * x - x) * 0x1p-200); > + } > + if (ix<0x3ffd) { /* |x|<0.25 */ > + x2 =3D x*x; > +#if LDBL_MANT_DIG =3D=3D 64 > + x4 =3D x2*x2; > + RETURNI(((T19*x2 + T17)*x4 + (T15*x2 + T13))*(x2*x*x2*x4*x4= ) + > + ((T11*x2 + T9)*x4 + (T7*x2 + T5))*(x2*x*x2) + > + T3*(x2*x) + x); > +#elif LDBL_MANT_DIG =3D=3D 113 > + dx2 =3D x2; > +#if 0 > + RETURNI(((((((((((((((T33*dx2 + T31)*dx2 + T29)*dx2 + T27)*= dx2 + > + T25)*x2 + T23)*x2 + T21)*x2 + T19)*x2 + T17)*x2 + > + T15)*x2 + T13)*x2 + T11)*x2 + T9)*x2 + T7)*x2 + T5)* > + (x2*x*x2) + > + T3*(x2*x) + x); > +#else > + long double q =3D ((((((((((((((T33*dx2 + T31)*dx2 + T29)*d= x2 + T27)*dx2 + > + T25)*x2 + T23)*x2 + T21)*x2 + T19)*x2 + T17)*x2 + > + T15)*x2 + T13)*x2 + T11)*x2 + T9)*x2 + T7)*x2 + T5)* > + (x2*x*x2); > + RETURNI(q + T3*(x2*x) + x); > +#endif > +#endif > + } > + k_hexpl(2*fabsl(x), &hi, &lo); > + if (ix<0x4001 && fabsl(x) < 1.5) /* |x|<1.5 */ > + z =3D divl(hi, lo, -0.5, hi, lo, 0.5); > + else > + z =3D one - one/(lo+0.5+hi); > + /* |x| >=3D 40, return +-1 */ > + } else { > + z =3D one - tiny; /* raise inexact flag */ > + } > + s =3D 1; > + if (jx<0) s =3D -1; > + RETURNI(s*z); > +} > diff --git a/newlib/libm/ld/s_tanl.c b/newlib/libm/ld/s_tanl.c > new file mode 100644 > index 000000000..0c5228ec8 > --- /dev/null > +++ b/newlib/libm/ld/s_tanl.c > @@ -0,0 +1,97 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2007 Steven G. Kargl > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice unmodified, this list of conditions, and the following > + * disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * Limited testing on pseudorandom numbers drawn within [0:4e8] shows > + * an accuracy of <=3D 1.5 ULP where 247024 values of x out of 40 millio= n > + * possibles resulted in tan(x) that exceeded 0.5 ULP (ie., 0.6%). > + */ > + > +#include > +#ifdef __i386__ > +#include > +#endif > + > +#include "math.h" > +#include "math_private.h" > +#if LDBL_MANT_DIG =3D=3D 64 > +#include "../ld80/e_rem_pio2l.h" > +#elif LDBL_MANT_DIG =3D=3D 113 > +#include "../ld128/e_rem_pio2l.h" > +#else > +#error "Unsupported long double format" > +#endif > + > +long double > +tanl(long double x) > +{ > + union IEEEl2bits z; > + int e0, s; > + long double y[2]; > + long double hi, lo; > + > + z.e =3D x; > + s =3D z.bits.sign; > + z.bits.sign =3D 0; > + > + /* If x =3D +-0 or x is subnormal, then tan(x) =3D x. */ > + if (z.bits.exp =3D=3D 0) > + return (x); > + > + /* If x =3D NaN or Inf, then tan(x) =3D NaN. */ > + if (z.bits.exp =3D=3D 32767) > + return ((x - x) / (x - x)); > + > + ENTERI(); > + > + /* Optimize the case where x is already within range. */ > + if (z.e < M_PI_4) { > + hi =3D __kernel_tanl(z.e, 0, 0); > + RETURNI(s ? -hi : hi); > + } > + > + e0 =3D __ieee754_rem_pio2l(x, y); > + hi =3D y[0]; > + lo =3D y[1]; > + > + switch (e0 & 3) { > + case 0: > + case 2: > + hi =3D __kernel_tanl(hi, lo, 0); > + break; > + case 1: > + case 3: > + hi =3D __kernel_tanl(hi, lo, 1); > + break; > + } > + > + RETURNI(hi); > +} > diff --git a/newlib/libm/ld/s_truncl.c b/newlib/libm/ld/s_truncl.c > new file mode 100644 > index 000000000..9e2b51132 > --- /dev/null > +++ b/newlib/libm/ld/s_truncl.c > @@ -0,0 +1,68 @@ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * > + * From: @(#)s_floor.c 5.1 93/09/24 > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * truncl(x) > + * Return x rounded toward 0 to integral value > + * Method: > + * Bit twiddling. > + * Exception: > + * Inexact flag raised if x not equal to truncl(x). > + */ > + > +#include > +#include > +#include > + > +#include "fpmath.h" > + > +#ifdef LDBL_IMPLICIT_NBIT > +#define MANH_SIZE (LDBL_MANH_SIZE + 1) > +#else > +#define MANH_SIZE LDBL_MANH_SIZE > +#endif > + > +static const long double huge =3D 1.0e300; > +static const float zero[] =3D { 0.0, -0.0 }; > + > +long double > +truncl(long double x) > +{ > + union IEEEl2bits u =3D { .e =3D x }; > + int e =3D u.bits.exp - LDBL_MAX_EXP + 1; > + > + if (e < MANH_SIZE - 1) { > + if (e < 0) { /* raise inexact if x !=3D = 0 */ > + if (huge + x > 0.0) > + u.e =3D zero[u.bits.sign]; > + } else { > + uint64_t m =3D ((1llu << MANH_SIZE) - 1) >> (e + 1)= ; > + if (((u.bits.manh & m) | u.bits.manl) =3D=3D 0) > + return (x); /* x is integral */ > + if (huge + x > 0.0) { /* raise inexact flag */ > + u.bits.manh &=3D ~m; > + u.bits.manl =3D 0; > + } > + } > + } else if (e < LDBL_MANT_DIG - 1) { > + uint64_t m =3D (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1)= ; > + if ((u.bits.manl & m) =3D=3D 0) > + return (x); /* x is integral */ > + if (huge + x > 0.0) /* raise inexact flag */ > + u.bits.manl &=3D ~m; > + } > + return (u.e); > +} > diff --git a/newlib/libm/ld128/b_tgammal.c b/newlib/libm/ld128/b_tgammal.= c > new file mode 100644 > index 000000000..1c995ab6d > --- /dev/null > +++ b/newlib/libm/ld128/b_tgammal.c > @@ -0,0 +1,57 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2013 David Chisnall > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + * > + * $FreeBSD$ > + */ > + > +#include > +#include > + > +/* > + * If long double is not the same size as double, then these will lose > + * precision and we should emit a warning whenever something links again= st > + * them. > + */ > +#if (LDBL_MANT_DIG > 53) > +#define WARN_IMPRECISE(x) \ > + __warn_references(x, # x " has lower than advertised precision"); > +#else > +#define WARN_IMPRECISE(x) > +#endif > +/* > + * Declare the functions as weak variants so that other libraries provid= ing > + * real versions can override them. > + */ > +#define DECLARE_WEAK(x)\ > + __weak_reference(imprecise_## x, x);\ > + WARN_IMPRECISE(x) > + > +#define DECLARE_IMPRECISE(f) \ > + long double imprecise_ ## f ## l(long double v) { return f(v); }\ > + DECLARE_WEAK(f ## l) > + > +DECLARE_IMPRECISE(tgamma); > diff --git a/newlib/libm/ld128/e_lgammal_r.c b/newlib/libm/ld128/e_lgamma= l_r.c > new file mode 100644 > index 000000000..53d3af17d > --- /dev/null > +++ b/newlib/libm/ld128/e_lgammal_r.c > @@ -0,0 +1,330 @@ > +/* @(#)e_lgamma_r.c 1.3 95/01/18 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See e_lgamma_r.c for complete comments. > + * > + * Converted to long double by Steven G. Kargl. > + */ > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +static const volatile double vzero =3D 0; > + > +static const double > +zero=3D 0, > +half=3D 0.5, > +one =3D 1; > + > +static const long double > +pi =3D 3.14159265358979323846264338327950288e+00L; > +/* > + * Domain y in [0x1p-119, 0.28], range ~[-1.4065e-36, 1.4065e-36]: > + * |(lgamma(2 - y) + y / 2) / y - a(y)| < 2**-119.1 > + */ > +static const long double > +a0 =3D 7.72156649015328606065120900824024296e-02L, > +a1 =3D 3.22467033424113218236207583323018498e-01L, > +a2 =3D 6.73523010531980951332460538330282217e-02L, > +a3 =3D 2.05808084277845478790009252803463129e-02L, > +a4 =3D 7.38555102867398526627292839296001626e-03L, > +a5 =3D 2.89051033074152328576829509522483468e-03L, > +a6 =3D 1.19275391170326097618357349881842913e-03L, > +a7 =3D 5.09669524743042462515256340206203019e-04L, > +a8 =3D 2.23154758453578096143609255559576017e-04L, > +a9 =3D 9.94575127818397632126978731542755129e-05L, > +a10 =3D 4.49262367375420471287545895027098145e-05L, > +a11 =3D 2.05072127845117995426519671481628849e-05L, > +a12 =3D 9.43948816959096748454087141447939513e-06L, > +a13 =3D 4.37486780697359330303852050718287419e-06L, > +a14 =3D 2.03920783892362558276037363847651809e-06L, > +a15 =3D 9.55191070057967287877923073200324649e-07L, > +a16 =3D 4.48993286185740853170657139487620560e-07L, > +a17 =3D 2.13107543597620911675316728179563522e-07L, > +a18 =3D 9.70745379855304499867546549551023473e-08L, > +a19 =3D 5.61889970390290257926487734695402075e-08L, > +a20 =3D 6.42739653024130071866684358960960951e-09L, > +a21 =3D 3.34491062143649291746195612991870119e-08L, > +a22 =3D -1.57068547394315223934653011440641472e-08L, > +a23 =3D 1.30812825422415841213733487745200632e-08L; > +/* > + * Domain x in [tc-0.24, tc+0.28], range ~[-6.3201e-37, 6.3201e-37]: > + * |(lgamma(x) - tf) - t(x - tc)| < 2**-120.3. > + */ > +static const long double > +tc =3D 1.46163214496836234126265954232572133e+00L, > +tf =3D -1.21486290535849608095514557177691584e-01L, > +tt =3D 1.57061739945077675484237837992951704e-36L, > +t0 =3D -1.99238329499314692728655623767019240e-36L, > +t1 =3D -6.08453430711711404116887457663281416e-35L, > +t2 =3D 4.83836122723810585213722380854828904e-01L, > +t3 =3D -1.47587722994530702030955093950668275e-01L, > +t4 =3D 6.46249402389127526561003464202671923e-02L, > +t5 =3D -3.27885410884813055008502586863748063e-02L, > +t6 =3D 1.79706751152103942928638276067164935e-02L, > +t7 =3D -1.03142230366363872751602029672767978e-02L, > +t8 =3D 6.10053602051788840313573150785080958e-03L, > +t9 =3D -3.68456960831637325470641021892968954e-03L, > +t10 =3D 2.25976482322181046611440855340968560e-03L, > +t11 =3D -1.40225144590445082933490395950664961e-03L, > +t12 =3D 8.78232634717681264035014878172485575e-04L, > +t13 =3D -5.54194952796682301220684760591403899e-04L, > +t14 =3D 3.51912956837848209220421213975000298e-04L, > +t15 =3D -2.24653443695947456542669289367055542e-04L, > +t16 =3D 1.44070395420840737695611929680511823e-04L, > +t17 =3D -9.27609865550394140067059487518862512e-05L, > +t18 =3D 5.99347334438437081412945428365433073e-05L, > +t19 =3D -3.88458388854572825603964274134801009e-05L, > +t20 =3D 2.52476631610328129217896436186551043e-05L, > +t21 =3D -1.64508584981658692556994212457518536e-05L, > +t22 =3D 1.07434583475987007495523340296173839e-05L, > +t23 =3D -7.03070407519397260929482550448878399e-06L, > +t24 =3D 4.60968590693753579648385629003100469e-06L, > +t25 =3D -3.02765473778832036018438676945512661e-06L, > +t26 =3D 1.99238771545503819972741288511303401e-06L, > +t27 =3D -1.31281299822614084861868817951788579e-06L, > +t28 =3D 8.60844432267399655055574642052370223e-07L, > +t29 =3D -5.64535486432397413273248363550536374e-07L, > +t30 =3D 3.99357783676275660934903139592727737e-07L, > +t31 =3D -2.95849029193433121795495215869311610e-07L, > +t32 =3D 1.37790144435073124976696250804940384e-07L; > +/* > + * Domain y in [-0.1, 0.232], range ~[-1.4046e-37, 1.4181e-37]: > + * |(lgamma(1 + y) + 0.5 * y) / y - u(y) / v(y)| < 2**-122.8 > + */ > +static const long double > +u0 =3D -7.72156649015328606065120900824024311e-02L, > +u1 =3D 4.24082772271938167430983113242482656e-01L, > +u2 =3D 2.96194003481457101058321977413332171e+00L, > +u3 =3D 6.49503267711258043997790983071543710e+00L, > +u4 =3D 7.40090051288150177152835698948644483e+00L, > +u5 =3D 4.94698036296756044610805900340723464e+00L, > +u6 =3D 2.00194224610796294762469550684947768e+00L, > +u7 =3D 4.82073087750608895996915051568834949e-01L, > +u8 =3D 6.46694052280506568192333848437585427e-02L, > +u9 =3D 4.17685526755100259316625348933108810e-03L, > +u10 =3D 9.06361003550314327144119307810053410e-05L, > +v1 =3D 5.15937098592887275994320496999951947e+00L, > +v2 =3D 1.14068418766251486777604403304717558e+01L, > +v3 =3D 1.41164839437524744055723871839748489e+01L, > +v4 =3D 1.07170702656179582805791063277960532e+01L, > +v5 =3D 5.14448694179047879915042998453632434e+00L, > +v6 =3D 1.55210088094585540637493826431170289e+00L, > +v7 =3D 2.82975732849424562719893657416365673e-01L, > +v8 =3D 2.86424622754753198010525786005443539e-02L, > +v9 =3D 1.35364253570403771005922441442688978e-03L, > +v10 =3D 1.91514173702398375346658943749580666e-05L, > +v11 =3D -3.25364686890242327944584691466034268e-08L; > +/* > + * Domain x in (2, 3], range ~[-1.3341e-36, 1.3536e-36]: > + * |(lgamma(y+2) - 0.5 * y) / y - s(y)/r(y)| < 2**-120.1 > + * with y =3D x - 2. > + */ > +static const long double > +s0 =3D -7.72156649015328606065120900824024297e-02L, > +s1 =3D 1.23221687850916448903914170805852253e-01L, > +s2 =3D 5.43673188699937239808255378293820020e-01L, > +s3 =3D 6.31998137119005233383666791176301800e-01L, > +s4 =3D 3.75885340179479850993811501596213763e-01L, > +s5 =3D 1.31572908743275052623410195011261575e-01L, > +s6 =3D 2.82528453299138685507186287149699749e-02L, > +s7 =3D 3.70262021550340817867688714880797019e-03L, > +s8 =3D 2.83374000312371199625774129290973648e-04L, > +s9 =3D 1.15091830239148290758883505582343691e-05L, > +s10 =3D 2.04203474281493971326506384646692446e-07L, > +s11 =3D 9.79544198078992058548607407635645763e-10L, > +r1 =3D 2.58037466655605285937112832039537492e+00L, > +r2 =3D 2.86289413392776399262513849911531180e+00L, > +r3 =3D 1.78691044735267497452847829579514367e+00L, > +r4 =3D 6.89400381446725342846854215600008055e-01L, > +r5 =3D 1.70135865462567955867134197595365343e-01L, > +r6 =3D 2.68794816183964420375498986152766763e-02L, > +r7 =3D 2.64617234244861832870088893332006679e-03L, > +r8 =3D 1.52881761239180800640068128681725702e-04L, > +r9 =3D 4.63264813762296029824851351257638558e-06L, > +r10 =3D 5.89461519146957343083848967333671142e-08L, > +r11 =3D 1.79027678176582527798327441636552968e-10L; > +/* > + * Domain z in [8, 0x1p70], range ~[-9.8214e-35, 9.8214e-35]: > + * |lgamma(x) - (x - 0.5) * (log(x) - 1) - w(1/x)| < 2**-113.0 > + */ > +static const long double > +w0 =3D 4.18938533204672741780329736405617738e-01L, > +w1 =3D 8.33333333333333333333333333332852026e-02L, > +w2 =3D -2.77777777777777777777777727810123528e-03L, > +w3 =3D 7.93650793650793650791708939493907380e-04L, > +w4 =3D -5.95238095238095234390450004444370959e-04L, > +w5 =3D 8.41750841750837633887817658848845695e-04L, > +w6 =3D -1.91752691752396849943172337347259743e-03L, > +w7 =3D 6.41025640880333069429106541459015557e-03L, > +w8 =3D -2.95506530801732133437990433080327074e-02L, > +w9 =3D 1.79644237328444101596766586979576927e-01L, > +w10 =3D -1.39240539108367641920172649259736394e+00L, > +w11 =3D 1.33987701479007233325288857758641761e+01L, > +w12 =3D -1.56363596431084279780966590116006255e+02L, > +w13 =3D 2.14830978044410267201172332952040777e+03L, > +w14 =3D -3.28636067474227378352761516589092334e+04L, > +w15 =3D 5.06201257747865138432663574251462485e+05L, > +w16 =3D -6.79720123352023636706247599728048344e+06L, > +w17 =3D 6.57556601705472106989497289465949255e+07L, > +w18 =3D -3.26229058141181783534257632389415580e+08L; > + > +static long double > +sin_pil(long double x) > +{ > + volatile long double vz; > + long double y,z; > + uint64_t lx, n; > + uint16_t hx; > + > + y =3D -x; > + > + vz =3D y+0x1.p112; > + z =3D vz-0x1.p112; > + if (z =3D=3D y) > + return zero; > + > + vz =3D y+0x1.p110; > + EXTRACT_LDBL128_WORDS(hx,lx,n,vz); > + z =3D vz-0x1.p110; > + if (z > y) { > + z -=3D 0.25; > + n--; > + } > + n &=3D 7; > + y =3D y - z + n * 0.25; > + > + switch (n) { > + case 0: y =3D __kernel_sinl(pi*y,zero,0); break; > + case 1: > + case 2: y =3D __kernel_cosl(pi*(0.5-y),zero); break; > + case 3: > + case 4: y =3D __kernel_sinl(pi*(one-y),zero,0); break; > + case 5: > + case 6: y =3D -__kernel_cosl(pi*(y-1.5),zero); break; > + default: y =3D __kernel_sinl(pi*(y-2.0),zero,0); break; > + } > + return -y; > +} > + > +long double > +lgammal_r(long double x, int *signgamp) > +{ > + long double nadj,p,p1,p2,p3,q,r,t,w,y,z; > + uint64_t llx,lx; > + int i; > + uint16_t hx,ix; > + > + EXTRACT_LDBL128_WORDS(hx,lx,llx,x); > + > + /* purge +-Inf and NaNs */ > + *signgamp =3D 1; > + ix =3D hx&0x7fff; > + if(ix=3D=3D0x7fff) return x*x; > + > + /* purge +-0 and tiny arguments */ > + *signgamp =3D 1-2*(hx>>15); > + if(ix<0x3fff-116) { /* |x|<2**-(p+3), return -log(|x|) = */ > + if((ix|lx|llx)=3D=3D0) > + return one/vzero; > + return -logl(fabsl(x)); > + } > + > + /* purge negative integers and start evaluation for other x < 0 */ > + if(hx&0x8000) { > + *signgamp =3D 1; > + if(ix>=3D0x3fff+112) /* |x|>=3D2**(p-1), must be -inte= ger */ > + return one/vzero; > + t =3D sin_pil(x); > + if(t=3D=3Dzero) return one/vzero; > + nadj =3D logl(pi/fabsl(t*x)); > + if(t + x =3D -x; > + } > + > + /* purge 1 and 2 */ > + if((ix=3D=3D0x3fff || ix=3D=3D0x4000) && (lx|llx)=3D=3D0) r =3D 0; > + /* for x < 2.0 */ > + else if(ix<0x4000) { > + if(x<=3D8.9999961853027344e-01) { > + r =3D -logl(x); > + if(x>=3D7.3159980773925781e-01) {y =3D 1-x; i=3D 0;} > + else if(x>=3D2.3163998126983643e-01) {y=3D x-(tc-1); i=3D1;= } > + else {y =3D x; i=3D2;} > + } else { > + r =3D 0; > + if(x>=3D1.7316312789916992e+00) {y=3D2-x;i=3D0;} > + else if(x>=3D1.2316322326660156e+00) {y=3Dx-tc;i=3D1;} > + else {y=3Dx-1;i=3D2;} > + } > + switch(i) { > + case 0: > + z =3D y*y; > + p1 =3D a0+z*(a2+z*(a4+z*(a6+z*(a8+z*(a10+z*(a12+z*(a14+z*(a= 16+ > + z*(a18+z*(a20+z*a22)))))))))); > + p2 =3D z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*(a11+z*(a13+z*(a15+ > + z*(a17+z*(a19+z*(a21+z*a23))))))))))); > + p =3D y*p1+p2; > + r +=3D p-y/2; break; > + case 1: > + p =3D t0+y*t1+tt+y*y*(t2+y*(t3+y*(t4+y*(t5+y*(t6+y*(t7+y*(t= 8+ > + y*(t9+y*(t10+y*(t11+y*(t12+y*(t13+y*(t14+y*(t15+y*(t16+ > + y*(t17+y*(t18+y*(t19+y*(t20+y*(t21+y*(t22+y*(t23+ > + y*(t24+y*(t25+y*(t26+y*(t27+y*(t28+y*(t29+y*(t30+ > + y*(t31+y*t32)))))))))))))))))))))))))))))); > + r +=3D tf + p; break; > + case 2: > + p1 =3D y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*(u5+y*(u6+y*(u7+ > + y*(u8+y*(u9+y*u10)))))))))); > + p2 =3D one+y*(v1+y*(v2+y*(v3+y*(v4+y*(v5+y*(v6+y*(v7+ > + y*(v8+y*(v9+y*(v10+y*v11)))))))))); > + r +=3D p1/p2-y/2; > + } > + } > + /* x < 8.0 */ > + else if(ix<0x4002) { > + i =3D x; > + y =3D x-i; > + p =3D y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*(s6+y*(s7+y*(s8+ > + y*(s9+y*(s10+y*s11))))))))))); > + q =3D one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*(r6+y*(r7+y*(r8+ > + y*(r9+y*(r10+y*r11)))))))))); > + r =3D y/2+p/q; > + z =3D 1; /* lgamma(1+s) =3D log(s) + lgamma(s) */ > + switch(i) { > + case 7: z *=3D (y+6); /* FALLTHRU */ > + case 6: z *=3D (y+5); /* FALLTHRU */ > + case 5: z *=3D (y+4); /* FALLTHRU */ > + case 4: z *=3D (y+3); /* FALLTHRU */ > + case 3: z *=3D (y+2); /* FALLTHRU */ > + r +=3D logl(z); break; > + } > + /* 8.0 <=3D x < 2**(p+3) */ > + } else if (ix<0x3fff+116) { > + t =3D logl(x); > + z =3D one/x; > + y =3D z*z; > + w =3D w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*(w6+y*(w7+y*(w8+ > + y*(w9+y*(w10+y*(w11+y*(w12+y*(w13+y*(w14+y*(w15+y*(w16+ > + y*(w17+y*w18))))))))))))))))); > + r =3D (x-half)*(t-one)+w; > + /* 2**(p+3) <=3D x <=3D inf */ > + } else > + r =3D x*(logl(x)-1); > + if(hx&0x8000) r =3D nadj - r; > + return r; > +} > diff --git a/newlib/libm/ld128/e_powl.c b/newlib/libm/ld128/e_powl.c > new file mode 100644 > index 000000000..12b92a1a9 > --- /dev/null > +++ b/newlib/libm/ld128/e_powl.c > @@ -0,0 +1,443 @@ > +/*- > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +/* > + * Copyright (c) 2008 Stephen L. Moshier > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the abov= e > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANT= IES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE F= OR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGE= S > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT = OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +/* powl(x,y) return x**y > + * > + * n > + * Method: Let x =3D 2 * (1+f) > + * 1. Compute and return log2(x) in two pieces: > + * log2(x) =3D w1 + w2, > + * where w1 has 113-53 =3D 60 bit trailing zeros. > + * 2. Perform y*log2(x) =3D n+y' by simulating multi-precision > + * arithmetic, where |y'|<=3D0.5. > + * 3. Return x**y =3D 2**n*exp(y'*log2) > + * > + * Special cases: > + * 1. (anything) ** 0 is 1 > + * 2. (anything) ** 1 is itself > + * 3. (anything) ** NAN is NAN > + * 4. NAN ** (anything except 0) is NAN > + * 5. +-(|x| > 1) ** +INF is +INF > + * 6. +-(|x| > 1) ** -INF is +0 > + * 7. +-(|x| < 1) ** +INF is +0 > + * 8. +-(|x| < 1) ** -INF is +INF > + * 9. +-1 ** +-INF is NAN > + * 10. +0 ** (+anything except 0, NAN) is +0 > + * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 > + * 12. +0 ** (-anything except 0, NAN) is +INF > + * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF > + * 14. -0 ** (odd integer) =3D -( +0 ** (odd integer) ) > + * 15. +INF ** (+anything except 0,NAN) is +INF > + * 16. +INF ** (-anything except 0,NAN) is +0 > + * 17. -INF ** (anything) =3D -0 ** (-anything) > + * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer= ) > + * 19. (-anything except 0 and inf) ** (non-integer) is NAN > + * > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > +#include > + > +#include "math_private.h" > + > +static const long double bp[] =3D { > + 1.0L, > + 1.5L, > +}; > + > +/* log_2(1.5) */ > +static const long double dp_h[] =3D { > + 0.0, > + 5.8496250072115607565592654282227158546448E-1L > +}; > + > +/* Low part of log_2(1.5) */ > +static const long double dp_l[] =3D { > + 0.0, > + 1.0579781240112554492329533686862998106046E-16L > +}; > + > +static const long double zero =3D 0.0L, > + one =3D 1.0L, > + two =3D 2.0L, > + two113 =3D 1.0384593717069655257060992658440192E34L, > + huge =3D 1.0e3000L, > + tiny =3D 1.0e-3000L; > + > +/* 3/2 log x =3D 3 z + z^3 + z^3 (z^2 R(z^2)) > + z =3D (x-1)/(x+1) > + 1 <=3D x <=3D 1.25 > + Peak relative error 2.3e-37 */ > +static const long double LN[] =3D > +{ > + -3.0779177200290054398792536829702930623200E1L, > + 6.5135778082209159921251824580292116201640E1L, > + -4.6312921812152436921591152809994014413540E1L, > + 1.2510208195629420304615674658258363295208E1L, > + -9.9266909031921425609179910128531667336670E-1L > +}; > +static const long double LD[] =3D > +{ > + -5.129862866715009066465422805058933131960E1L, > + 1.452015077564081884387441590064272782044E2L, > + -1.524043275549860505277434040464085593165E2L, > + 7.236063513651544224319663428634139768808E1L, > + -1.494198912340228235853027849917095580053E1L > + /* 1.0E0 */ > +}; > + > +/* exp(x) =3D 1 + x - x / (1 - 2 / (x - x^2 R(x^2))) > + 0 <=3D x <=3D 0.5 > + Peak relative error 5.7e-38 */ > +static const long double PN[] =3D > +{ > + 5.081801691915377692446852383385968225675E8L, > + 9.360895299872484512023336636427675327355E6L, > + 4.213701282274196030811629773097579432957E4L, > + 5.201006511142748908655720086041570288182E1L, > + 9.088368420359444263703202925095675982530E-3L, > +}; > +static const long double PD[] =3D > +{ > + 3.049081015149226615468111430031590411682E9L, > + 1.069833887183886839966085436512368982758E8L, > + 8.259257717868875207333991924545445705394E5L, > + 1.872583833284143212651746812884298360922E3L, > + /* 1.0E0 */ > +}; > + > +static const long double > + /* ln 2 */ > + lg2 =3D 6.9314718055994530941723212145817656807550E-1L, > + lg2_h =3D 6.9314718055994528622676398299518041312695E-1L, > + lg2_l =3D 2.3190468138462996154948554638754786504121E-17L, > + ovt =3D 8.0085662595372944372e-0017L, > + /* 2/(3*log(2)) */ > + cp =3D 9.6179669392597560490661645400126142495110E-1L, > + cp_h =3D 9.6179669392597555432899980587535537779331E-1L, > + cp_l =3D 5.0577616648125906047157785230014751039424E-17L; > + > +long double > +powl(long double x, long double y) > +{ > + long double z, ax, z_h, z_l, p_h, p_l; > + long double yy1, t1, t2, r, s, t, u, v, w; > + long double s2, s_h, s_l, t_h, t_l; > + int32_t i, j, k, yisint, n; > + u_int32_t ix, iy; > + int32_t hx, hy; > + ieee_quad_shape_type o, p, q; > + > + p.value =3D x; > + hx =3D p.parts32.mswhi; > + ix =3D hx & 0x7fffffff; > + > + q.value =3D y; > + hy =3D q.parts32.mswhi; > + iy =3D hy & 0x7fffffff; > + > + > + /* y=3D=3Dzero: x**0 =3D 1 */ > + if ((iy | q.parts32.mswlo | q.parts32.lswhi | q.parts32.lswlo) =3D=3D = 0) > + return one; > + > + /* 1.0**y =3D 1; -1.0**+-Inf =3D 1 */ > + if (x =3D=3D one) > + return one; > + if (x =3D=3D -1.0L && iy =3D=3D 0x7fff0000 > + && (q.parts32.mswlo | q.parts32.lswhi | q.parts32.lswlo) =3D=3D 0) > + return one; > + > + /* +-NaN return x+y */ > + if ((ix > 0x7fff0000) > + || ((ix =3D=3D 0x7fff0000) > + && ((p.parts32.mswlo | p.parts32.lswhi | p.parts32.lswlo) !=3D 0)= ) > + || (iy > 0x7fff0000) > + || ((iy =3D=3D 0x7fff0000) > + && ((q.parts32.mswlo | q.parts32.lswhi | q.parts32.lswlo) !=3D 0)= )) > + return nan_mix(x, y); > + > + /* determine if y is an odd int when x < 0 > + * yisint =3D 0 ... y is not an integer > + * yisint =3D 1 ... y is an odd int > + * yisint =3D 2 ... y is an even int > + */ > + yisint =3D 0; > + if (hx < 0) > + { > + if (iy >=3D 0x40700000) /* 2^113 */ > + yisint =3D 2; /* even integer y */ > + else if (iy >=3D 0x3fff0000) /* 1.0 */ > + { > + if (floorl (y) =3D=3D y) > + { > + z =3D 0.5 * y; > + if (floorl (z) =3D=3D z) > + yisint =3D 2; > + else > + yisint =3D 1; > + } > + } > + } > + > + /* special value of y */ > + if ((q.parts32.mswlo | q.parts32.lswhi | q.parts32.lswlo) =3D=3D 0) > + { > + if (iy =3D=3D 0x7fff0000) /* y is +-inf */ > + { > + if (((ix - 0x3fff0000) | p.parts32.mswlo | p.parts32.lswhi | > + p.parts32.lswlo) =3D=3D 0) > + return y - y; /* +-1**inf is NaN */ > + else if (ix >=3D 0x3fff0000) /* (|x|>1)**+-inf =3D inf,0 */ > + return (hy >=3D 0) ? y : zero; > + else /* (|x|<1)**-,+inf =3D inf,0 */ > + return (hy < 0) ? -y : zero; > + } > + if (iy =3D=3D 0x3fff0000) > + { /* y is +-1 */ > + if (hy < 0) > + return one / x; > + else > + return x; > + } > + if (hy =3D=3D 0x40000000) > + return x * x; /* y is 2 */ > + if (hy =3D=3D 0x3ffe0000) > + { /* y is 0.5 */ > + if (hx >=3D 0) /* x >=3D +0 */ > + return sqrtl (x); > + } > + } > + > + ax =3D fabsl (x); > + /* special value of x */ > + if ((p.parts32.mswlo | p.parts32.lswhi | p.parts32.lswlo) =3D=3D 0) > + { > + if (ix =3D=3D 0x7fff0000 || ix =3D=3D 0 || ix =3D=3D 0x3fff0000) > + { > + z =3D ax; /*x is +-0,+-inf,+-1 */ > + if (hy < 0) > + z =3D one / z; /* z =3D (1/|x|) */ > + if (hx < 0) > + { > + if (((ix - 0x3fff0000) | yisint) =3D=3D 0) > + { > + z =3D (z - z) / (z - z); /* (-1)**non-int is NaN *= / > + } > + else if (yisint =3D=3D 1) > + z =3D -z; /* (x<0)**odd =3D -(|x|**odd) */ > + } > + return z; > + } > + } > + > + /* (x<0)**(non-int) is NaN */ > + if (((((u_int32_t) hx >> 31) - 1) | yisint) =3D=3D 0) > + return (x - x) / (x - x); > + > + /* |y| is huge. > + 2^-16495 =3D 1/2 of smallest representable value. > + If (1 - 1/131072)^y underflows, y > 1.4986e9 */ > + if (iy > 0x401d654b) > + { > + /* if (1 - 2^-113)^y underflows, y > 1.1873e38 */ > + if (iy > 0x407d654b) > + { > + if (ix <=3D 0x3ffeffff) > + return (hy < 0) ? huge * huge : tiny * tiny; > + if (ix >=3D 0x3fff0000) > + return (hy > 0) ? huge * huge : tiny * tiny; > + } > + /* over/underflow if x is not close to one */ > + if (ix < 0x3ffeffff) > + return (hy < 0) ? huge * huge : tiny * tiny; > + if (ix > 0x3fff0000) > + return (hy > 0) ? huge * huge : tiny * tiny; > + } > + > + n =3D 0; > + /* take care subnormal number */ > + if (ix < 0x00010000) > + { > + ax *=3D two113; > + n -=3D 113; > + o.value =3D ax; > + ix =3D o.parts32.mswhi; > + } > + n +=3D ((ix) >> 16) - 0x3fff; > + j =3D ix & 0x0000ffff; > + /* determine interval */ > + ix =3D j | 0x3fff0000; /* normalize ix */ > + if (j <=3D 0x3988) > + k =3D 0; /* |x| + else if (j < 0xbb67) > + k =3D 1; /* |x| + else > + { > + k =3D 0; > + n +=3D 1; > + ix -=3D 0x00010000; > + } > + > + o.value =3D ax; > + o.parts32.mswhi =3D ix; > + ax =3D o.value; > + > + /* compute s =3D s_h+s_l =3D (x-1)/(x+1) or (x-1.5)/(x+1.5) */ > + u =3D ax - bp[k]; /* bp[0]=3D1.0, bp[1]=3D1.5 */ > + v =3D one / (ax + bp[k]); > + s =3D u * v; > + s_h =3D s; > + > + o.value =3D s_h; > + o.parts32.lswlo =3D 0; > + o.parts32.lswhi &=3D 0xf8000000; > + s_h =3D o.value; > + /* t_h=3Dax+bp[k] High */ > + t_h =3D ax + bp[k]; > + o.value =3D t_h; > + o.parts32.lswlo =3D 0; > + o.parts32.lswhi &=3D 0xf8000000; > + t_h =3D o.value; > + t_l =3D ax - (t_h - bp[k]); > + s_l =3D v * ((u - s_h * t_h) - s_h * t_l); > + /* compute log(ax) */ > + s2 =3D s * s; > + u =3D LN[0] + s2 * (LN[1] + s2 * (LN[2] + s2 * (LN[3] + s2 * LN[4]))); > + v =3D LD[0] + s2 * (LD[1] + s2 * (LD[2] + s2 * (LD[3] + s2 * (LD[4] + = s2)))); > + r =3D s2 * s2 * u / v; > + r +=3D s_l * (s_h + s); > + s2 =3D s_h * s_h; > + t_h =3D 3.0 + s2 + r; > + o.value =3D t_h; > + o.parts32.lswlo =3D 0; > + o.parts32.lswhi &=3D 0xf8000000; > + t_h =3D o.value; > + t_l =3D r - ((t_h - 3.0) - s2); > + /* u+v =3D s*(1+...) */ > + u =3D s_h * t_h; > + v =3D s_l * t_h + t_l * s; > + /* 2/(3log2)*(s+...) */ > + p_h =3D u + v; > + o.value =3D p_h; > + o.parts32.lswlo =3D 0; > + o.parts32.lswhi &=3D 0xf8000000; > + p_h =3D o.value; > + p_l =3D v - (p_h - u); > + z_h =3D cp_h * p_h; /* cp_h+cp_l =3D 2/(3*log2) */ > + z_l =3D cp_l * p_h + p_l * cp + dp_l[k]; > + /* log2(ax) =3D (s+..)*2/(3*log2) =3D n + dp_h + z_h + z_l */ > + t =3D (long double) n; > + t1 =3D (((z_h + z_l) + dp_h[k]) + t); > + o.value =3D t1; > + o.parts32.lswlo =3D 0; > + o.parts32.lswhi &=3D 0xf8000000; > + t1 =3D o.value; > + t2 =3D z_l - (((t1 - t) - dp_h[k]) - z_h); > + > + /* s (sign of result -ve**odd) =3D -1 else =3D 1 */ > + s =3D one; > + if (((((u_int32_t) hx >> 31) - 1) | (yisint - 1)) =3D=3D 0) > + s =3D -one; /* (-ve)**(odd int) */ > + > + /* split up y into yy1+y2 and compute (yy1+y2)*(t1+t2) */ > + yy1 =3D y; > + o.value =3D yy1; > + o.parts32.lswlo =3D 0; > + o.parts32.lswhi &=3D 0xf8000000; > + yy1 =3D o.value; > + p_l =3D (y - yy1) * t1 + y * t2; > + p_h =3D yy1 * t1; > + z =3D p_l + p_h; > + o.value =3D z; > + j =3D o.parts32.mswhi; > + if (j >=3D 0x400d0000) /* z >=3D 16384 */ > + { > + /* if z > 16384 */ > + if (((j - 0x400d0000) | o.parts32.mswlo | o.parts32.lswhi | > + o.parts32.lswlo) !=3D 0) > + return s * huge * huge; /* overflow */ > + else > + { > + if (p_l + ovt > z - p_h) > + return s * huge * huge; /* overflow */ > + } > + } > + else if ((j & 0x7fffffff) >=3D 0x400d01b9) /* z <=3D -16495 */ > + { > + /* z < -16495 */ > + if (((j - 0xc00d01bc) | o.parts32.mswlo | o.parts32.lswhi | > + o.parts32.lswlo) > + !=3D 0) > + return s * tiny * tiny; /* underflow */ > + else > + { > + if (p_l <=3D z - p_h) > + return s * tiny * tiny; /* underflow */ > + } > + } > + /* compute 2**(p_h+p_l) */ > + i =3D j & 0x7fffffff; > + k =3D (i >> 16) - 0x3fff; > + n =3D 0; > + if (i > 0x3ffe0000) > + { /* if |z| > 0.5, set n =3D [z+0.5] = */ > + n =3D floorl (z + 0.5L); > + t =3D n; > + p_h -=3D t; > + } > + t =3D p_l + p_h; > + o.value =3D t; > + o.parts32.lswlo =3D 0; > + o.parts32.lswhi &=3D 0xf8000000; > + t =3D o.value; > + u =3D t * lg2_h; > + v =3D (p_l - (t - p_h)) * lg2 + t * lg2_l; > + z =3D u + v; > + w =3D v - (z - u); > + /* exp(z) */ > + t =3D z * z; > + u =3D PN[0] + t * (PN[1] + t * (PN[2] + t * (PN[3] + t * PN[4]))); > + v =3D PD[0] + t * (PD[1] + t * (PD[2] + t * (PD[3] + t))); > + t1 =3D z - t * u / v; > + r =3D (z * t1) / (t1 - two) - (w + z * w); > + z =3D one - (r - z); > + o.value =3D z; > + j =3D o.parts32.mswhi; > + j +=3D (n << 16); > + if ((j >> 16) <=3D 0) > + z =3D scalbnl (z, n); /* subnormal output */ > + else > + { > + o.parts32.mswhi =3D j; > + z =3D o.value; > + } > + return s * z; > +} > diff --git a/newlib/libm/ld128/e_rem_pio2l.h b/newlib/libm/ld128/e_rem_pi= o2l.h > new file mode 100644 > index 000000000..7516ced49 > --- /dev/null > +++ b/newlib/libm/ld128/e_rem_pio2l.h > @@ -0,0 +1,135 @@ > +/* From: @(#)e_rem_pio2.c 1.4 95/01/18 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * > + * Optimized by Bruce D. Evans. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* ld128 version of __ieee754_rem_pio2l(x,y) > + * > + * return the remainder of x rem pi/2 in y[0]+y[1] > + * use __kernel_rem_pio2() > + */ > + > +#include > + > +#include "math.h" > +#include "math_private.h" > +#include "../ld/fpmath.h" > + > +#define BIAS (LDBL_MAX_EXP - 1) > + > +/* > + * XXX need to verify that nonzero integer multiples of pi/2 within the > + * range get no closer to a long double than 2**-140, or that > + * ilogb(x) + ilogb(min_delta) < 45 - -140. > + */ > +/* > + * invpio2: 113 bits of 2/pi > + * pio2_1: first 68 bits of pi/2 > + * pio2_1t: pi/2 - pio2_1 > + * pio2_2: second 68 bits of pi/2 > + * pio2_2t: pi/2 - (pio2_1+pio2_2) > + * pio2_3: third 68 bits of pi/2 > + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) > + */ > + > +static const double > +zero =3D 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ > +two24 =3D 1.67772160000000000000e+07; /* 0x41700000, 0x00000000 */ > + > +static const long double > +invpio2 =3D 6.3661977236758134307553505349005747e-01L, /* 0x145= f306dc9c882a53f84eafa3ea6a.0p-113 */ > +pio2_1 =3D 1.5707963267948966192292994253909555e+00L, /* 0x192= 1fb54442d18469800000000000.0p-112 */ > +pio2_1t =3D 2.0222662487959507323996846200947577e-21L, /* 0x131= 98a2e03707344a4093822299f3.0p-181 */ > +pio2_2 =3D 2.0222662487959507323994779168837751e-21L, /* 0x131= 98a2e03707344a400000000000.0p-181 */ > +pio2_2t =3D 2.0670321098263988236496903051604844e-43L, /* 0x127= 044533e63a0105df531d89cd91.0p-254 */ > +pio2_3 =3D 2.0670321098263988236499468110329591e-43L, /* 0x127= 044533e63a0105e00000000000.0p-254 */ > +pio2_3t =3D -2.5650587247459238361625433492959285e-65L; /* -0x159= c4ec64ddaeb5f78671cbfb2210.0p-327 */ > + > +static inline __always_inline int > +__ieee754_rem_pio2l(long double x, long double *y) > +{ > + union IEEEl2bits u,u1; > + long double z,w,t,r,fn; > + double tx[5],ty[3]; > + int64_t n; > + int e0,ex,i,j,nx; > + int16_t expsign; > + > + u.e =3D x; > + expsign =3D u.xbits.expsign; > + ex =3D expsign & 0x7fff; > + if (ex < BIAS + 45 || ex =3D=3D BIAS + 45 && > + u.bits.manh < 0x921fb54442d1LL) { > + /* |x| ~< 2^45*(pi/2), medium size */ > + /* TODO: use only double precision for fn, as in expl(). */ > + fn =3D rnintl(x * invpio2); > + n =3D i64rint(fn); > + r =3D x-fn*pio2_1; > + w =3D fn*pio2_1t; /* 1st round good to 180 bit */ > + { > + union IEEEl2bits u2; > + int ex1; > + j =3D ex; > + y[0] =3D r-w; > + u2.e =3D y[0]; > + ex1 =3D u2.xbits.expsign & 0x7fff; > + i =3D j-ex1; > + if(i>51) { /* 2nd iteration needed, good to 248 */ > + t =3D r; > + w =3D fn*pio2_2; > + r =3D t-w; > + w =3D fn*pio2_2t-((t-r)-w); > + y[0] =3D r-w; > + u2.e =3D y[0]; > + ex1 =3D u2.xbits.expsign & 0x7fff; > + i =3D j-ex1; > + if(i>119) { /* 3rd iteration need, 316 bits acc */ > + t =3D r; /* will cover all possible cases */ > + w =3D fn*pio2_3; > + r =3D t-w; > + w =3D fn*pio2_3t-((t-r)-w); > + y[0] =3D r-w; > + } > + } > + } > + y[1] =3D (r-y[0])-w; > + return n; > + } > + /* > + * all other (large) arguments > + */ > + if(ex=3D=3D0x7fff) { /* x is inf or NaN */ > + y[0]=3Dy[1]=3Dx-x; return 0; > + } > + /* set z =3D scalbn(|x|,ilogb(x)-23) */ > + u1.e =3D x; > + e0 =3D ex - BIAS - 23; /* e0 =3D ilogb(|x|)-23; */ > + u1.xbits.expsign =3D ex - e0; > + z =3D u1.e; > + for(i=3D0;i<4;i++) { > + tx[i] =3D (double)((int32_t)(z)); > + z =3D (z-tx[i])*two24; > + } > + tx[4] =3D z; > + nx =3D 5; > + while(tx[nx-1]=3D=3Dzero) nx--; /* skip zero term */ > + n =3D __kernel_rem_pio2(tx,ty,e0,nx,3); > + t =3D (long double)ty[2] + ty[1]; > + r =3D t + ty[0]; > + w =3D ty[0] - (r - t); > + if(expsign<0) {y[0] =3D -r; y[1] =3D -w; return -n;} > + y[0] =3D r; y[1] =3D w; return n; > +} > diff --git a/newlib/libm/ld128/invtrig.c b/newlib/libm/ld128/invtrig.c > new file mode 100644 > index 000000000..ab93732c8 > --- /dev/null > +++ b/newlib/libm/ld128/invtrig.c > @@ -0,0 +1,102 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2008 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include "invtrig.h" > + > +/* > + * asinl() and acosl() > + */ > +const long double > +pS0 =3D 1.66666666666666666666666666666700314e-01L, > +pS1 =3D -7.32816946414566252574527475428622708e-01L, > +pS2 =3D 1.34215708714992334609030036562143589e+00L, > +pS3 =3D -1.32483151677116409805070261790752040e+00L, > +pS4 =3D 7.61206183613632558824485341162121989e-01L, > +pS5 =3D -2.56165783329023486777386833928147375e-01L, > +pS6 =3D 4.80718586374448793411019434585413855e-02L, > +pS7 =3D -4.42523267167024279410230886239774718e-03L, > +pS8 =3D 1.44551535183911458253205638280410064e-04L, > +pS9 =3D -2.10558957916600254061591040482706179e-07L, > +qS1 =3D -4.84690167848739751544716485245697428e+00L, > +qS2 =3D 9.96619113536172610135016921140206980e+00L, > +qS3 =3D -1.13177895428973036660836798461641458e+01L, > +qS4 =3D 7.74004374389488266169304117714658761e+00L, > +qS5 =3D -3.25871986053534084709023539900339905e+00L, > +qS6 =3D 8.27830318881232209752469022352928864e-01L, > +qS7 =3D -1.18768052702942805423330715206348004e-01L, > +qS8 =3D 8.32600764660522313269101537926539470e-03L, > +qS9 =3D -1.99407384882605586705979504567947007e-04L; > + > +/* > + * atanl() > + */ > +const long double atanhi[] =3D { > + 4.63647609000806116214256231461214397e-01L, > + 7.85398163397448309615660845819875699e-01L, > + 9.82793723247329067985710611014666038e-01L, > + 1.57079632679489661923132169163975140e+00L, > +}; > + > +const long double atanlo[] =3D { > + 4.89509642257333492668618435220297706e-36L, > + 2.16795253253094525619926100651083806e-35L, > + -2.31288434538183565909319952098066272e-35L, > + 4.33590506506189051239852201302167613e-35L, > +}; > + > +const long double aT[] =3D { > + 3.33333333333333333333333333333333125e-01L, > + -1.99999999999999999999999999999180430e-01L, > + 1.42857142857142857142857142125269827e-01L, > + -1.11111111111111111111110834490810169e-01L, > + 9.09090909090909090908522355708623681e-02L, > + -7.69230769230769230696553844935357021e-02L, > + 6.66666666666666660390096773046256096e-02L, > + -5.88235294117646671706582985209643694e-02L, > + 5.26315789473666478515847092020327506e-02L, > + -4.76190476189855517021024424991436144e-02L, > + 4.34782608678695085948531993458097026e-02L, > + -3.99999999632663469330634215991142368e-02L, > + 3.70370363987423702891250829918659723e-02L, > + -3.44827496515048090726669907612335954e-02L, > + 3.22579620681420149871973710852268528e-02L, > + -3.03020767654269261041647570626778067e-02L, > + 2.85641979882534783223403715930946138e-02L, > + -2.69824879726738568189929461383741323e-02L, > + 2.54194698498808542954187110873675769e-02L, > + -2.35083879708189059926183138130183215e-02L, > + 2.04832358998165364349957325067131428e-02L, > + -1.54489555488544397858507248612362957e-02L, > + 8.64492360989278761493037861575248038e-03L, > + -2.58521121597609872727919154569765469e-03L, > +}; > + > +const long double pi_lo =3D 8.67181013012378102479704402604335225e-35L; > diff --git a/newlib/libm/ld128/invtrig.h b/newlib/libm/ld128/invtrig.h > new file mode 100644 > index 000000000..423b56847 > --- /dev/null > +++ b/newlib/libm/ld128/invtrig.h > @@ -0,0 +1,115 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2008 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + * > + * $FreeBSD$ > + */ > + > +#include > + > +#include "fpmath.h" > + > +#define BIAS (LDBL_MAX_EXP - 1) > +#define MANH_SIZE (LDBL_MANH_SIZE + 1) > + > +/* Approximation thresholds. */ > +#define ASIN_LINEAR (BIAS - 56) /* 2**-56 */ > +#define ACOS_CONST (BIAS - 113) /* 2**-113 */ > +#define ATAN_CONST (BIAS + 113) /* 2**113 */ > +#define ATAN_LINEAR (BIAS - 56) /* 2**-56 */ > + > +/* 0.95 */ > +#define THRESH ((0xe666666666666666ULL>>(64-(MANH_SIZE-1)))|LDBL_N= BIT) > + > +/* Constants shared by the long double inverse trig functions. */ > +#define pS0 _ItL_pS0 > +#define pS1 _ItL_pS1 > +#define pS2 _ItL_pS2 > +#define pS3 _ItL_pS3 > +#define pS4 _ItL_pS4 > +#define pS5 _ItL_pS5 > +#define pS6 _ItL_pS6 > +#define pS7 _ItL_pS7 > +#define pS8 _ItL_pS8 > +#define pS9 _ItL_pS9 > +#define qS1 _ItL_qS1 > +#define qS2 _ItL_qS2 > +#define qS3 _ItL_qS3 > +#define qS4 _ItL_qS4 > +#define qS5 _ItL_qS5 > +#define qS6 _ItL_qS6 > +#define qS7 _ItL_qS7 > +#define qS8 _ItL_qS8 > +#define qS9 _ItL_qS9 > +#define atanhi _ItL_atanhi > +#define atanlo _ItL_atanlo > +#define aT _ItL_aT > +#define pi_lo _ItL_pi_lo > + > +#define pio2_hi atanhi[3] > +#define pio2_lo atanlo[3] > +#define pio4_hi atanhi[1] > + > +/* Constants shared by the long double inverse trig functions. */ > +extern const long double pS0, pS1, pS2, pS3, pS4, pS5, pS6, pS7, pS8, pS= 9; > +extern const long double qS1, qS2, qS3, qS4, qS5, qS6, qS7, qS8, qS9; > +extern const long double atanhi[], atanlo[], aT[]; > +extern const long double pi_lo; > + > +static inline long double > +P(long double x) > +{ > + > + return (x * (pS0 + x * (pS1 + x * (pS2 + x * (pS3 + x * \ > + (pS4 + x * (pS5 + x * (pS6 + x * (pS7 + x * (pS8 + x * \ > + pS9)))))))))); > +} > + > +static inline long double > +Q(long double x) > +{ > + > + return (1.0 + x * (qS1 + x * (qS2 + x * (qS3 + x * (qS4 + x * \ > + (qS5 + x * (qS6 + x * (qS7 + x * (qS8 + x * qS9))))))))); > +} > + > +static inline long double > +T_even(long double x) > +{ > + > + return (aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] + x * \ > + (aT[8] + x * (aT[10] + x * (aT[12] + x * (aT[14] + x * \ > + (aT[16] + x * (aT[18] + x * (aT[20] + x * aT[22])))))))))))= ; > +} > + > +static inline long double > +T_odd(long double x) > +{ > + > + return (aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] + x * \ > + (aT[9] + x * (aT[11] + x * (aT[13] + x * (aT[15] + x * \ > + (aT[17] + x * (aT[19] + x * (aT[21] + x * aT[23])))))))))))= ; > +} > diff --git a/newlib/libm/ld128/k_cosl.c b/newlib/libm/ld128/k_cosl.c > new file mode 100644 > index 000000000..422357bf8 > --- /dev/null > +++ b/newlib/libm/ld128/k_cosl.c > @@ -0,0 +1,59 @@ > +/* From: @(#)k_cos.c 1.3 95/01/18 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * ld128 version of k_cos.c. See ../src/k_cos.c for most comments. > + */ > + > +#include "math_private.h" > + > +/* > + * Domain [-0.7854, 0.7854], range ~[-1.17e-39, 1.19e-39]: > + * |cos(x) - c(x))| < 2**-129.3 > + * > + * 113-bit precision requires more care than 64-bit precision, since > + * simple methods give a minimax polynomial with coefficient for x^2 > + * that is 1 ulp below 0.5, but we want it to be precisely 0.5. See > + * ../ld80/k_cosl.c for more details. > + */ > +static const double > +one =3D 1.0; > +static const long double > +C1 =3D 4.16666666666666666666666666666666667e-02L, > +C2 =3D -1.38888888888888888888888888888888834e-03L, > +C3 =3D 2.48015873015873015873015873015446795e-05L, > +C4 =3D -2.75573192239858906525573190949988493e-07L, > +C5 =3D 2.08767569878680989792098886701451072e-09L, > +C6 =3D -1.14707455977297247136657111139971865e-11L, > +C7 =3D 4.77947733238738518870113294139830239e-14L, > +C8 =3D -1.56192069685858079920640872925306403e-16L, > +C9 =3D 4.11031762320473354032038893429515732e-19L, > +C10=3D -8.89679121027589608738005163931958096e-22L, > +C11=3D 1.61171797801314301767074036661901531e-24L, > +C12=3D -2.46748624357670948912574279501044295e-27L; > + > +long double > +__kernel_cosl(long double x, long double y) > +{ > + long double hz,z,r,w; > + > + z =3D x*x; > + r =3D z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*(C7+ > + z*(C8+z*(C9+z*(C10+z*(C11+z*C12))))))))))); > + hz =3D 0.5*z; > + w =3D one-hz; > + return w + (((one-w)-hz) + (z*r-x*y)); > +} > diff --git a/newlib/libm/ld128/k_expl.h b/newlib/libm/ld128/k_expl.h > new file mode 100644 > index 000000000..159338fe3 > --- /dev/null > +++ b/newlib/libm/ld128/k_expl.h > @@ -0,0 +1,324 @@ > +/* from: FreeBSD: head/lib/msun/ld128/s_expl.c 251345 2013-06-03 20:09:2= 2Z kargl */ > + > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2009-2013 Steven G. Kargl > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice unmodified, this list of conditions, and the following > + * disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + * > + * Optimized by Bruce D. Evans. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * ld128 version of k_expl.h. See ../ld80/s_expl.c for most comments. > + * > + * See ../src/e_exp.c and ../src/k_exp.h for precision-independent comme= nts > + * about the secondary kernels. > + */ > + > +#define INTERVALS 128 > +#define LOG2_INTERVALS 7 > +#define BIAS (LDBL_MAX_EXP - 1) > + > +static const double > +/* > + * ln2/INTERVALS =3D L1+L2 (hi+lo decomposition for multiplication). L1= must > + * have at least 22 (=3D log2(|LDBL_MIN_EXP-extras|) + log2(INTERVALS)) = lowest > + * bits zero so that multiplication of it by n is exact. > + */ > +INV_L =3D 1.8466496523378731e+2, /* 0x171547652b82fe.0p-4= 5 */ > +L2 =3D -1.0253670638894731e-29; /* -0x1.9ff0342542fc3p-97= */ > +static const long double > +/* 0x1.62e42fefa39ef35793c768000000p-8 */ > +L1 =3D 5.41521234812457272982212595914567508e-3L; > + > +/* > + * XXX values in hex in comments have been lost (or were never present) > + * from here. > + */ > +static const long double > +/* > + * Domain [-0.002708, 0.002708], range ~[-2.4021e-38, 2.4234e-38]: > + * |exp(x) - p(x)| < 2**-124.9 > + * (0.002708 is ln2/(2*INTERVALS) rounded up a little). > + * > + * XXX the coeffs aren't very carefully rounded, and I get 3.6 more bits= . > + */ > +A2 =3D 0.5, > +A3 =3D 1.66666666666666666666666666651085500e-1L, > +A4 =3D 4.16666666666666666666666666425885320e-2L, > +A5 =3D 8.33333333333333333334522877160175842e-3L, > +A6 =3D 1.38888888888888888889971139751596836e-3L; > + > +static const double > +A7 =3D 1.9841269841269470e-4, /* 0x1.a01a01a019f91p-13= */ > +A8 =3D 2.4801587301585286e-5, /* 0x1.71de3ec75a967p-19= */ > +A9 =3D 2.7557324277411235e-6, /* 0x1.71de3ec75a967p-19= */ > +A10 =3D 2.7557333722375069e-7; /* 0x1.27e505ab56259p-22= */ > + > +static const struct { > + /* > + * hi must be rounded to at most 106 bits so that multiplication > + * by r1 in expm1l() is exact, but it is rounded to 88 bits due to > + * historical accidents. > + * > + * XXX it is wasteful to use long double for both hi and lo. ld128 > + * exp2l() uses only float for lo (in a very differently organized > + * table; ld80 exp2l() is different again. It uses 2 doubles in a > + * table organized like this one. 1 double and 1 float would > + * suffice). There are different packing/locality/alignment/cachin= g > + * problems with these methods. > + * > + * XXX C's bad %a format makes the bits unreadable. They happen > + * to all line up for the hi values 1 before the point and 88 > + * in 22 nybbles, but for the low values the nybbles are shifted > + * randomly. > + */ > + long double hi; > + long double lo; > +} tbl[INTERVALS] =3D { > + 0x1p0L, 0x0p0L, > + 0x1.0163da9fb33356d84a66aep0L, 0x3.36dcdfa4003ec04c360be2404078p-92= L, > + 0x1.02c9a3e778060ee6f7cacap0L, 0x4.f7a29bde93d70a2cabc5cb89ba10p-92= L, > + 0x1.04315e86e7f84bd738f9a2p0L, 0xd.a47e6ed040bb4bfc05af6455e9b8p-96= L, > + 0x1.059b0d31585743ae7c548ep0L, 0xb.68ca417fe53e3495f7df4baf84a0p-92= L, > + 0x1.0706b29ddf6ddc6dc403a8p0L, 0x1.d87b27ed07cb8b092ac75e311753p-88= L, > + 0x1.0874518759bc808c35f25cp0L, 0x1.9427fa2b041b2d6829d8993a0d01p-88= L, > + 0x1.09e3ecac6f3834521e060cp0L, 0x5.84d6b74ba2e023da730e7fccb758p-92= L, > + 0x1.0b5586cf9890f6298b92b6p0L, 0x1.1842a98364291408b3ceb0a2a2bbp-88= L, > + 0x1.0cc922b7247f7407b705b8p0L, 0x9.3dc5e8aac564e6fe2ef1d431fd98p-92= L, > + 0x1.0e3ec32d3d1a2020742e4ep0L, 0x1.8af6a552ac4b358b1129e9f966a4p-88= L, > + 0x1.0fb66affed31af232091dcp0L, 0x1.8a1426514e0b627bda694a400a27p-88= L, > + 0x1.11301d0125b50a4ebbf1aep0L, 0xd.9318ceac5cc47ab166ee57427178p-92= L, > + 0x1.12abdc06c31cbfb92bad32p0L, 0x4.d68e2f7270bdf7cedf94eb1cb818p-92= L, > + 0x1.1429aaea92ddfb34101942p0L, 0x1.b2586d01844b389bea7aedd221d4p-88= L, > + 0x1.15a98c8a58e512480d573cp0L, 0x1.d5613bf92a2b618ee31b376c2689p-88= L, > + 0x1.172b83c7d517adcdf7c8c4p0L, 0x1.0eb14a792035509ff7d758693f24p-88= L, > + 0x1.18af9388c8de9bbbf70b9ap0L, 0x3.c2505c97c0102e5f1211941d2840p-92= L, > + 0x1.1a35beb6fcb753cb698f68p0L, 0x1.2d1c835a6c30724d5cfae31b84e5p-88= L, > + 0x1.1bbe084045cd39ab1e72b4p0L, 0x4.27e35f9acb57e473915519a1b448p-92= L, > + 0x1.1d4873168b9aa7805b8028p0L, 0x9.90f07a98b42206e46166cf051d70p-92= L, > + 0x1.1ed5022fcd91cb8819ff60p0L, 0x1.121d1e504d36c47474c9b7de6067p-88= L, > + 0x1.2063b88628cd63b8eeb028p0L, 0x1.50929d0fc487d21c2b84004264dep-88= L, > + 0x1.21f49917ddc962552fd292p0L, 0x9.4bdb4b61ea62477caa1dce823ba0p-92= L, > + 0x1.2387a6e75623866c1fadb0p0L, 0x1.c15cb593b0328566902df69e4de2p-88= L, > + 0x1.251ce4fb2a63f3582ab7dep0L, 0x9.e94811a9c8afdcf796934bc652d0p-92= L, > + 0x1.26b4565e27cdd257a67328p0L, 0x1.d3b249dce4e9186ddd5ff44e6b08p-92= L, > + 0x1.284dfe1f5638096cf15cf0p0L, 0x3.ca0967fdaa2e52d7c8106f2e262cp-92= L, > + 0x1.29e9df51fdee12c25d15f4p0L, 0x1.a24aa3bca890ac08d203fed80a07p-88= L, > + 0x1.2b87fd0dad98ffddea4652p0L, 0x1.8fcab88442fdc3cb6de4519165edp-88= L, > + 0x1.2d285a6e4030b40091d536p0L, 0xd.075384589c1cd1b3e4018a6b1348p-92= L, > + 0x1.2ecafa93e2f5611ca0f45cp0L, 0x1.523833af611bdcda253c554cf278p-88= L, > + 0x1.306fe0a31b7152de8d5a46p0L, 0x3.05c85edecbc27343629f502f1af2p-92= L, > + 0x1.32170fc4cd8313539cf1c2p0L, 0x1.008f86dde3220ae17a005b6412bep-88= L, > + 0x1.33c08b26416ff4c9c8610cp0L, 0x1.96696bf95d1593039539d94d662bp-88= L, > + 0x1.356c55f929ff0c94623476p0L, 0x3.73af38d6d8d6f9506c9bbc93cbc0p-92= L, > + 0x1.371a7373aa9caa7145502ep0L, 0x1.4547987e3e12516bf9c699be432fp-88= L, > + 0x1.38cae6d05d86585a9cb0d8p0L, 0x1.bed0c853bd30a02790931eb2e8f0p-88= L, > + 0x1.3a7db34e59ff6ea1bc9298p0L, 0x1.e0a1d336163fe2f852ceeb134067p-88= L, > + 0x1.3c32dc313a8e484001f228p0L, 0xb.58f3775e06ab66353001fae9fca0p-92= L, > + 0x1.3dea64c12342235b41223ep0L, 0x1.3d773fba2cb82b8244267c54443fp-92= L, > + 0x1.3fa4504ac801ba0bf701aap0L, 0x4.1832fb8c1c8dbdff2c49909e6c60p-92= L, > + 0x1.4160a21f72e29f84325b8ep0L, 0x1.3db61fb352f0540e6ba05634413ep-88= L, > + 0x1.431f5d950a896dc7044394p0L, 0x1.0ccec81e24b0caff7581ef4127f7p-92= L, > + 0x1.44e086061892d03136f408p0L, 0x1.df019fbd4f3b48709b78591d5cb5p-88= L, > + 0x1.46a41ed1d005772512f458p0L, 0x1.229d97df404ff21f39c1b594d3a8p-88= L, > + 0x1.486a2b5c13cd013c1a3b68p0L, 0x1.062f03c3dd75ce8757f780e6ec99p-88= L, > + 0x1.4a32af0d7d3de672d8bcf4p0L, 0x6.f9586461db1d878b1d148bd3ccb8p-92= L, > + 0x1.4bfdad5362a271d4397afep0L, 0xc.42e20e0363ba2e159c579f82e4b0p-92= L, > + 0x1.4dcb299fddd0d63b36ef1ap0L, 0x9.e0cc484b25a5566d0bd5f58ad238p-92= L, > + 0x1.4f9b2769d2ca6ad33d8b68p0L, 0x1.aa073ee55e028497a329a7333dbap-88= L, > + 0x1.516daa2cf6641c112f52c8p0L, 0x4.d822190e718226177d7608d20038p-92= L, > + 0x1.5342b569d4f81df0a83c48p0L, 0x1.d86a63f4e672a3e429805b049465p-88= L, > + 0x1.551a4ca5d920ec52ec6202p0L, 0x4.34ca672645dc6c124d6619a87574p-92= L, > + 0x1.56f4736b527da66ecb0046p0L, 0x1.64eb3c00f2f5ab3d801d7cc7272dp-88= L, > + 0x1.58d12d497c7fd252bc2b72p0L, 0x1.43bcf2ec936a970d9cc266f0072fp-88= L, > + 0x1.5ab07dd48542958c930150p0L, 0x1.91eb345d88d7c81280e069fbdb63p-88= L, > + 0x1.5c9268a5946b701c4b1b80p0L, 0x1.6986a203d84e6a4a92f179e71889p-88= L, > + 0x1.5e76f15ad21486e9be4c20p0L, 0x3.99766a06548a05829e853bdb2b52p-92= L, > + 0x1.605e1b976dc08b076f592ap0L, 0x4.86e3b34ead1b4769df867b9c89ccp-92= L, > + 0x1.6247eb03a5584b1f0fa06ep0L, 0x1.d2da42bb1ceaf9f732275b8aef30p-88= L, > + 0x1.6434634ccc31fc76f8714cp0L, 0x4.ed9a4e41000307103a18cf7a6e08p-92= L, > + 0x1.66238825522249127d9e28p0L, 0x1.b8f314a337f4dc0a3adf1787ff74p-88= L, > + 0x1.68155d44ca973081c57226p0L, 0x1.b9f32706bfe4e627d809a85dcc66p-88= L, > + 0x1.6a09e667f3bcc908b2fb12p0L, 0x1.66ea957d3e3adec17512775099dap-88= L, > + 0x1.6c012750bdabeed76a9980p0L, 0xf.4f33fdeb8b0ecd831106f57b3d00p-96= L, > + 0x1.6dfb23c651a2ef220e2cbep0L, 0x1.bbaa834b3f11577ceefbe6c1c411p-92= L, > + 0x1.6ff7df9519483cf87e1b4ep0L, 0x1.3e213bff9b702d5aa477c12523cep-88= L, > + 0x1.71f75e8ec5f73dd2370f2ep0L, 0xf.0acd6cb434b562d9e8a20adda648p-92= L, > + 0x1.73f9a48a58173bd5c9a4e6p0L, 0x8.ab1182ae217f3a7681759553e840p-92= L, > + 0x1.75feb564267c8bf6e9aa32p0L, 0x1.a48b27071805e61a17b954a2dad8p-88= L, > + 0x1.780694fde5d3f619ae0280p0L, 0x8.58b2bb2bdcf86cd08e35fb04c0f0p-92= L, > + 0x1.7a11473eb0186d7d51023ep0L, 0x1.6cda1f5ef42b66977960531e821bp-88= L, > + 0x1.7c1ed0130c1327c4933444p0L, 0x1.937562b2dc933d44fc828efd4c9cp-88= L, > + 0x1.7e2f336cf4e62105d02ba0p0L, 0x1.5797e170a1427f8fcdf5f3906108p-88= L, > + 0x1.80427543e1a11b60de6764p0L, 0x9.a354ea706b8e4d8b718a672bf7c8p-92= L, > + 0x1.82589994cce128acf88afap0L, 0xb.34a010f6ad65cbbac0f532d39be0p-92= L, > + 0x1.8471a4623c7acce52f6b96p0L, 0x1.c64095370f51f48817914dd78665p-88= L, > + 0x1.868d99b4492ec80e41d90ap0L, 0xc.251707484d73f136fb5779656b70p-92= L, > + 0x1.88ac7d98a669966530bcdep0L, 0x1.2d4e9d61283ef385de170ab20f96p-88= L, > + 0x1.8ace5422aa0db5ba7c55a0p0L, 0x1.92c9bb3e6ed61f2733304a346d8fp-88= L, > + 0x1.8cf3216b5448bef2aa1cd0p0L, 0x1.61c55d84a9848f8c453b3ca8c946p-88= L, > + 0x1.8f1ae991577362b982745cp0L, 0x7.2ed804efc9b4ae1458ae946099d4p-92= L, > + 0x1.9145b0b91ffc588a61b468p0L, 0x1.f6b70e01c2a90229a4c4309ea719p-88= L, > + 0x1.93737b0cdc5e4f4501c3f2p0L, 0x5.40a22d2fc4af581b63e8326efe9cp-92= L, > + 0x1.95a44cbc8520ee9b483694p0L, 0x1.a0fc6f7c7d61b2b3a22a0eab2cadp-88= L, > + 0x1.97d829fde4e4f8b9e920f8p0L, 0x1.1e8bd7edb9d7144b6f6818084cc7p-88= L, > + 0x1.9a0f170ca07b9ba3109b8cp0L, 0x4.6737beb19e1eada6825d3c557428p-92= L, > + 0x1.9c49182a3f0901c7c46b06p0L, 0x1.1f2be58ddade50c217186c90b457p-88= L, > + 0x1.9e86319e323231824ca78ep0L, 0x6.4c6e010f92c082bbadfaf605cfd4p-92= L, > + 0x1.a0c667b5de564b29ada8b8p0L, 0xc.ab349aa0422a8da7d4512edac548p-92= L, > + 0x1.a309bec4a2d3358c171f76p0L, 0x1.0daad547fa22c26d168ea762d854p-88= L, > + 0x1.a5503b23e255c8b424491cp0L, 0xa.f87bc8050a405381703ef7caff50p-92= L, > + 0x1.a799e1330b3586f2dfb2b0p0L, 0x1.58f1a98796ce8908ae852236ca94p-88= L, > + 0x1.a9e6b5579fdbf43eb243bcp0L, 0x1.ff4c4c58b571cf465caf07b4b9f5p-88= L, > + 0x1.ac36bbfd3f379c0db966a2p0L, 0x1.1265fc73e480712d20f8597a8e7bp-88= L, > + 0x1.ae89f995ad3ad5e8734d16p0L, 0x1.73205a7fbc3ae675ea440b162d6cp-88= L, > + 0x1.b0e07298db66590842acdep0L, 0x1.c6f6ca0e5dcae2aafffa7a0554cbp-88= L, > + 0x1.b33a2b84f15faf6bfd0e7ap0L, 0x1.d947c2575781dbb49b1237c87b6ep-88= L, > + 0x1.b59728de559398e3881110p0L, 0x1.64873c7171fefc410416be0a6525p-88= L, > + 0x1.b7f76f2fb5e46eaa7b081ap0L, 0xb.53c5354c8903c356e4b625aacc28p-92= L, > + 0x1.ba5b030a10649840cb3c6ap0L, 0xf.5b47f297203757e1cc6eadc8bad0p-92= L, > + 0x1.bcc1e904bc1d2247ba0f44p0L, 0x1.b3d08cd0b20287092bd59be4ad98p-88= L, > + 0x1.bf2c25bd71e088408d7024p0L, 0x1.18e3449fa073b356766dfb568ff4p-88= L, > + 0x1.c199bdd85529c2220cb12ap0L, 0x9.1ba6679444964a36661240043970p-96= L, > + 0x1.c40ab5fffd07a6d14df820p0L, 0xf.1828a5366fd387a7bdd54cdf7300p-92= L, > + 0x1.c67f12e57d14b4a2137fd2p0L, 0xf.2b301dd9e6b151a6d1f9d5d5f520p-96= L, > + 0x1.c8f6d9406e7b511acbc488p0L, 0x5.c442ddb55820171f319d9e5076a8p-96= L, > + 0x1.cb720dcef90691503cbd1ep0L, 0x9.49db761d9559ac0cb6dd3ed599e0p-92= L, > + 0x1.cdf0b555dc3f9c44f8958ep0L, 0x1.ac51be515f8c58bdfb6f5740a3a4p-88= L, > + 0x1.d072d4a07897b8d0f22f20p0L, 0x1.a158e18fbbfc625f09f4cca40874p-88= L, > + 0x1.d2f87080d89f18ade12398p0L, 0x9.ea2025b4c56553f5cdee4c924728p-92= L, > + 0x1.d5818dcfba48725da05aeap0L, 0x1.66e0dca9f589f559c0876ff23830p-88= L, > + 0x1.d80e316c98397bb84f9d04p0L, 0x8.805f84bec614de269900ddf98d28p-92= L, > + 0x1.da9e603db3285708c01a5ap0L, 0x1.6d4c97f6246f0ec614ec95c99392p-88= L, > + 0x1.dd321f301b4604b695de3cp0L, 0x6.30a393215299e30d4fb73503c348p-96= L, > + 0x1.dfc97337b9b5eb968cac38p0L, 0x1.ed291b7225a944efd5bb5524b927p-88= L, > + 0x1.e264614f5a128a12761fa0p0L, 0x1.7ada6467e77f73bf65e04c95e29dp-88= L, > + 0x1.e502ee78b3ff6273d13014p0L, 0x1.3991e8f49659e1693be17ae1d2f9p-88= L, > + 0x1.e7a51fbc74c834b548b282p0L, 0x1.23786758a84f4956354634a416cep-88= L, > + 0x1.ea4afa2a490d9858f73a18p0L, 0xf.5db301f86dea20610ceee13eb7b8p-92= L, > + 0x1.ecf482d8e67f08db0312fap0L, 0x1.949cef462010bb4bc4ce72a900dfp-88= L, > + 0x1.efa1bee615a27771fd21a8p0L, 0x1.2dac1f6dd5d229ff68e46f27e3dfp-88= L, > + 0x1.f252b376bba974e8696fc2p0L, 0x1.6390d4c6ad5476b5162f40e1d9a9p-88= L, > + 0x1.f50765b6e4540674f84b76p0L, 0x2.862baff99000dfc4352ba29b8908p-92= L, > + 0x1.f7bfdad9cbe138913b4bfep0L, 0x7.2bd95c5ce7280fa4d2344a3f5618p-92= L, > + 0x1.fa7c1819e90d82e90a7e74p0L, 0xb.263c1dc060c36f7650b4c0f233a8p-92= L, > + 0x1.fd3c22b8f71f10975ba4b2p0L, 0x1.2bcf3a5e12d269d8ad7c1a4a8875p-88= L > +}; > + > +/* > + * Kernel for expl(x). x must be finite and not tiny or huge. > + * "tiny" is anything that would make us underflow (|A6*x^6| < ~LDBL_MIN= ). > + * "huge" is anything that would make fn*L1 inexact (|x| > ~2**17*ln2). > + */ > +static inline void > +__k_expl(long double x, long double *hip, long double *lop, int *kp) > +{ > + long double q, r, r1, t; > + double dr, fn, r2; > + int n, n2; > + > + /* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */ > + fn =3D rnint((double)x * INV_L); > + n =3D irint(fn); > + n2 =3D (unsigned)n % INTERVALS; > + /* Depend on the sign bit being propagated: */ > + *kp =3D n >> LOG2_INTERVALS; > + r1 =3D x - fn * L1; > + r2 =3D fn * -L2; > + r =3D r1 + r2; > + > + /* Evaluate expl(endpoint[n2] + r1 + r2) =3D tbl[n2] * expl(r1 + r2= ). */ > + dr =3D r; > + q =3D r2 + r * r * (A2 + r * (A3 + r * (A4 + r * (A5 + r * (A6 + > + dr * (A7 + dr * (A8 + dr * (A9 + dr * A10)))))))); > + t =3D tbl[n2].lo + tbl[n2].hi; > + *hip =3D tbl[n2].hi; > + *lop =3D tbl[n2].lo + t * (q + r1); > +} > + > +/* > + * XXX: the rest of the functions are identical for ld80 and ld128. > + * However, we should use scalbnl() for ld128, since long double > + * multiplication was very slow on sparc64 and no new evaluation has > + * been made for aarch64 and/or riscv. > + */ > + > +static inline void > +k_hexpl(long double x, long double *hip, long double *lop) > +{ > + float twopkm1; > + int k; > + > + __k_expl(x, hip, lop, &k); > + SET_FLOAT_WORD(twopkm1, 0x3f800000 + ((k - 1) << 23)); > + *hip *=3D twopkm1; > + *lop *=3D twopkm1; > +} > + > +static inline long double > +hexpl(long double x) > +{ > + long double hi, lo, twopkm2; > + int k; > + > + twopkm2 =3D 1; > + __k_expl(x, &hi, &lo, &k); > + SET_LDBL_EXPSIGN(twopkm2, BIAS + k - 2); > + return (lo + hi) * 2 * twopkm2; > +} > + > +#ifdef _COMPLEX_H > +/* > + * See ../src/k_exp.c for details. > + */ > +static inline long double complex > +__ldexp_cexpl(long double complex z, int expt) > +{ > + long double c, exp_x, hi, lo, s; > + long double x, y, scale1, scale2; > + int half_expt, k; > + > + x =3D creall(z); > + y =3D cimagl(z); > + __k_expl(x, &hi, &lo, &k); > + > + exp_x =3D (lo + hi) * 0x1p16382L; > + expt +=3D k - 16382; > + > + scale1 =3D 1; > + half_expt =3D expt / 2; > + SET_LDBL_EXPSIGN(scale1, BIAS + half_expt); > + scale2 =3D 1; > + SET_LDBL_EXPSIGN(scale2, BIAS + expt - half_expt); > + > + sincosl(y, &s, &c); > + return (CMPLXL(c * exp_x * scale1 * scale2, > + s * exp_x * scale1 * scale2)); > +} > +#endif /* _COMPLEX_H */ > diff --git a/newlib/libm/ld128/k_sinl.c b/newlib/libm/ld128/k_sinl.c > new file mode 100644 > index 000000000..09472d65f > --- /dev/null > +++ b/newlib/libm/ld128/k_sinl.c > @@ -0,0 +1,59 @@ > +/* From: @(#)k_sin.c 1.3 95/01/18 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * ld128 version of k_sin.c. See ../src/k_sin.c for most comments. > + */ > + > +#include "math_private.h" > + > +static const double > +half =3D 0.5; > + > +/* > + * Domain [-0.7854, 0.7854], range ~[-1.53e-37, 1.659e-37] > + * |sin(x)/x - s(x)| < 2**-122.1 > + * > + * See ../ld80/k_cosl.c for more details about the polynomial. > + */ > +static const long double > +S1 =3D -0.16666666666666666666666666666666666606732416116558L, > +S2 =3D 0.0083333333333333333333333333333331135404851288270047L, > +S3 =3D -0.00019841269841269841269841269839935785325638310428717L, > +S4 =3D 0.27557319223985890652557316053039946268333231205686e-5L, > +S5 =3D -0.25052108385441718775048214826384312253862930064745e-7L, > +S6 =3D 0.16059043836821614596571832194524392581082444805729e-9L, > +S7 =3D -0.76471637318198151807063387954939213287488216303768e-12L, > +S8 =3D 0.28114572543451292625024967174638477283187397621303e-14L; > + > +static const double > +S9 =3D -0.82206352458348947812512122163446202498005154296863e-17, > +S10 =3D 0.19572940011906109418080609928334380560135358385256e-19, > +S11 =3D -0.38680813379701966970673724299207480965452616911420e-22, > +S12 =3D 0.64038150078671872796678569586315881020659912139412e-25; > + > +long double > +__kernel_sinl(long double x, long double y, int iy) > +{ > + long double z,r,v; > + > + z =3D x*x; > + v =3D z*x; > + r =3D S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*(S8+ > + z*(S9+z*(S10+z*(S11+z*S12))))))))); > + if(iy=3D=3D0) return x+v*(S1+z*r); > + else return x-((z*(half*y-v*r)-y)-v*S1); > +} > diff --git a/newlib/libm/ld128/s_erfl.c b/newlib/libm/ld128/s_erfl.c > new file mode 100644 > index 000000000..e29c9691f > --- /dev/null > +++ b/newlib/libm/ld128/s_erfl.c > @@ -0,0 +1,329 @@ > +/* @(#)s_erf.c 5.1 93/09/24 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See s_erf.c for complete comments. > + * > + * Converted to long double by Steven G. Kargl. > + */ > +#include > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +/* XXX Prevent compilers from erroneously constant folding these: */ > +static const volatile long double tiny =3D 0x1p-10000L; > + > +static const double > +half=3D 0.5, > +one =3D 1, > +two =3D 2; > +/* > + * In the domain [0, 2**-40], only the first term in the power series > + * expansion of erf(x) is used. The magnitude of the first neglected > + * terms is less than 2**-120. > + */ > +static const long double > +efx =3D 1.28379167095512573896158903121545167e-01L, /* 0xecbff6a7, 0x= 481dd788, 0xb64d21a8, 0xeb06fc3f */ > +efx8 =3D 1.02703333676410059116927122497236133e+00L, /* 0xecbff6a7, 0x= 481dd788, 0xb64d21a8, 0xeb06ff3f */ > +/* > + * Domain [0, 0.84375], range ~[-1.919e-38, 1.919e-38]: > + * |(erf(x) - x)/x - pp(x)/qq(x)| < 2**-125.29 > + */ > +pp0 =3D 1.28379167095512573896158903121545167e-01L, /* 0x3ffc06eb, 0x= a8214db6, 0x88d71d48, 0xa7f6bfec */ > +pp1 =3D -3.14931554396568573802046931159683404e-01L, /* 0xbffd427d, 0x= 6ada7263, 0x547eb096, 0x95f37463 */ > +pp2 =3D -5.27514920282183487103576956956725309e-02L, /* 0xbffab023, 0x= e5a271e3, 0xb0e79b01, 0x2f7ac962 */ > +pp3 =3D -1.13202828509005281355609495523452713e-02L, /* 0xbff872f1, 0x= 6a5023a1, 0xe08b3884, 0x326af20f */ > +pp4 =3D -9.18626155872522453865998391206048506e-04L, /* 0xbff4e19f, 0x= ea5fb024, 0x43247a37, 0xe430b06c */ > +pp5 =3D -7.87518862406176274922506447157284230e-05L, /* 0xbff14a4f, 0x= 31a85fe0, 0x7fff2204, 0x09c49b37 */ > +pp6 =3D -3.42357944472240436548115331090560881e-06L, /* 0xbfeccb81, 0x= 4b43c336, 0xcd2eb6c2, 0x903f2d87 */ > +pp7 =3D -1.37317432573890412634717890726745428e-07L, /* 0xbfe826e3, 0x= 0e915eb6, 0x42aee414, 0xf7e36805 */ > +pp8 =3D -2.71115170113861755855049008732113726e-09L, /* 0xbfe2749e, 0x= 2b94fd00, 0xecb4d166, 0x0efb91f8 */ > +pp9 =3D -3.37925756196555959454018189718117864e-11L, /* 0xbfdc293e, 0x= 1d9060cb, 0xd043204a, 0x314cd7f0 */ > +qq1 =3D 4.76672625471551170489978555182449450e-01L, /* 0x3ffde81c, 0x= de6531f0, 0x76803bee, 0x526e29e9 */ > +qq2 =3D 1.06713144672281502058807525850732240e-01L, /* 0x3ffbb518, 0x= d7a6bb74, 0xcd9bdd33, 0x7601eee5 */ > +qq3 =3D 1.47747613127513761102189201923147490e-02L, /* 0x3ff8e423, 0x= ae527e18, 0xf12cb447, 0x723b4749 */ > +qq4 =3D 1.39939377672028671891148770908874816e-03L, /* 0x3ff56ed7, 0x= ba055d84, 0xc21b45c4, 0x388d1812 */ > +qq5 =3D 9.44302939359455241271983309378738276e-05L, /* 0x3ff18c11, 0x= c18c99a4, 0x86d0fe09, 0x46387b4c */ > +qq6 =3D 4.56199342312522842161301671745365650e-06L, /* 0x3fed3226, 0x= 73421d05, 0x08875300, 0x32fa1432 */ > +qq7 =3D 1.53019260483764773845294600092361197e-07L, /* 0x3fe8489b, 0x= 3a63f627, 0x2b9ad2ce, 0x26516e57 */ > +qq8 =3D 3.25542691121324805094777901250005508e-09L, /* 0x3fe2bf6c, 0x= 26d93a29, 0x9142be7c, 0x9f1dd043 */ > +qq9 =3D 3.37405581964478060434410167262684979e-11L; /* 0x3fdc28c8, 0x= fb8fa1be, 0x10e57eec, 0xaa19e49f */ > + > +static const long double > +erx =3D 8.42700792949714894142232424201210961e-01L, /* 0x3ffeaf76, 0x= 7a741088, 0xb0000000, 0x00000000 */ > +/* > + * Domain [0.84375, 1.25], range ~[-2.521e-36, 2.523e-36]: > + * |(erf(x) - erx) - pa(x)/qa(x)| < 2**-120.15 > + */ > +pa0 =3D -2.48010117891186017024438233323795897e-17L, /* 0xbfc7c97f, 0x= 77812279, 0x6c877f22, 0xef4bfb2e */ > +pa1 =3D 4.15107497420594680894327969504526489e-01L, /* 0x3ffda911, 0x= f096fbc2, 0x55662005, 0x2337fa64 */ > +pa2 =3D -3.94180628087084846724448515851892609e-02L, /* 0xbffa42e9, 0x= ab54528c, 0xad529da1, 0x6efc2af3 */ > +pa3 =3D 4.48897599625192107295954790681677462e-02L, /* 0x3ffa6fbc, 0x= a65edba1, 0x0e4cbcea, 0x73ef9a31 */ > +pa4 =3D 8.02069252143016600110972019232995528e-02L, /* 0x3ffb4887, 0x= 0e8b548e, 0x3230b417, 0x11b553b3 */ > +pa5 =3D -1.02729816533435279443621120242391295e-02L, /* 0xbff850a0, 0x= 041de3ee, 0xd5bca6c9, 0x4ef5f9f2 */ > +pa6 =3D 5.70777694530755634864821094419982095e-03L, /* 0x3ff77610, 0x= 9b501e10, 0x4c978382, 0x742df68f */ > +pa7 =3D 1.22635150233075521018231779267077071e-03L, /* 0x3ff5417b, 0x= 0e623682, 0x60327da0, 0x96b9219e */ > +pa8 =3D 5.36100234820204569428412542856666503e-04L, /* 0x3ff41912, 0x= 27ceb4c1, 0x1d3298ec, 0x84ced627 */ > +pa9 =3D -1.97753571846365167177187858667583165e-04L, /* 0xbff29eb8, 0x= 23f5bcf3, 0x15c83c46, 0xe4fda98b */ > +pa10 =3D 6.19333039900846970674794789568415105e-05L, /* 0x3ff103c4, 0x= 60f88e46, 0xc0c9fb02, 0x13cc7fc1 */ > +pa11 =3D -5.40531400436645861492290270311751349e-06L, /* 0xbfed6abe, 0x= 9665f8a8, 0xdd0ad3ba, 0xe5dc0ee3 */ > +qa1 =3D 9.05041313265490487793231810291907851e-01L, /* 0x3ffecf61, 0x= 93340222, 0xe9930620, 0xc4e61168 */ > +qa2 =3D 6.79848064708886864767240880834868092e-01L, /* 0x3ffe5c15, 0x= 0ba858dc, 0xf7900ae9, 0xfea1e09a */ > +qa3 =3D 4.04720609926471677581066689316516445e-01L, /* 0x3ffd9e6f, 0x= 145e9b00, 0x6d8c1749, 0xd2928623 */ > +qa4 =3D 1.69183273898369996364661075664302225e-01L, /* 0x3ffc5a7c, 0x= c2a363c1, 0xd6c19097, 0xef9b4063 */ > +qa5 =3D 7.44476185988067992342479750486764248e-02L, /* 0x3ffb30ef, 0x= fc7259ef, 0x1bcbb089, 0x686dd62d */ > +qa6 =3D 2.02981172725892407200420389604788573e-02L, /* 0x3ff94c90, 0x= 7976cb0e, 0x21e1d36b, 0x0f09ca2b */ > +qa7 =3D 6.94281866271607668268269403102277234e-03L, /* 0x3ff7c701, 0x= 2b193250, 0xc5d46ecc, 0x374843d8 */ > +qa8 =3D 1.12952275469171559611651594706820034e-03L, /* 0x3ff52818, 0x= fd2a7c06, 0xd13e38fd, 0xda4b34f5 */ > +qa9 =3D 3.13736683241992737197226578597710179e-04L, /* 0x3ff348fa, 0x= 0cb48d18, 0x051f849b, 0x135ccf74 */ > +qa10 =3D 1.17037675204033225470121134087771410e-05L, /* 0x3fee88b6, 0x= 98f47704, 0xa5d8f8f2, 0xc6422e11 */ > +qa11 =3D 4.61312518293853991439362806880973592e-06L, /* 0x3fed3594, 0x= e31db94f, 0x3592b693, 0xed4386b4 */ > +qa12 =3D -1.02158572037456893687737553657431771e-06L; /* 0xbfeb123a, 0x= d60d9b1e, 0x1f6fdeb9, 0x7dc8410a */ > +/* > + * Domain [1.25,2.85715], range ~[-2.922e-37,2.922e-37]: > + * |log(x*erfc(x)) + x**2 + 0.5625 - ra(x)/sa(x)| < 2**-121.36 > + */ > +static const long double > +ra0 =3D -9.86494292470069009555706994426014461e-03L, /* 0xbff84341, 0x= 239e8709, 0xe941b06a, 0xcb4b6ec5 */ > +ra1 =3D -1.13580436992565640457579040117568870e+00L, /* 0xbfff22c4, 0x= 133f7c0d, 0x72d5e231, 0x2eb1ee3f */ > +ra2 =3D -4.89744330295291950661185707066921755e+01L, /* 0xc00487cb, 0x= a38b4fc2, 0xc136695b, 0xc1df8047 */ > +ra3 =3D -1.10766149300215937173768072715352140e+03L, /* 0xc00914ea, 0x= 55e6beb3, 0xabc50e07, 0xb6e5664d */ > +ra4 =3D -1.49991031232170934967642795601952100e+04L, /* 0xc00cd4b8, 0x= d33243e6, 0xffbf6545, 0x3c57ef6e */ > +ra5 =3D -1.29805749738318462882524181556996692e+05L, /* 0xc00ffb0d, 0x= bfeed9b6, 0x5b2a3ff4, 0xe245bd3c */ > +ra6 =3D -7.42828497044940065828871976644647850e+05L, /* 0xc0126ab5, 0x= 8fe7caca, 0x473352d9, 0xcd4e0c90 */ > +ra7 =3D -2.85637299581890734287995171242421106e+06L, /* 0xc0145cad, 0x= a7f76fe7, 0x3e358051, 0x1799f927 */ > +ra8 =3D -7.40674797129824999383748865571026084e+06L, /* 0xc015c412, 0x= 6fe29c02, 0x298ad158, 0x7d24e45c */ > +ra9 =3D -1.28653420911930973914078724204151759e+07L, /* 0xc016889e, 0x= 7c2eb0dc, 0x95d5863b, 0x0aa34dc3 */ > +ra10 =3D -1.47198163599330179552932489109452638e+07L, /* 0xc016c136, 0x= 90b84923, 0xf9bcb497, 0x19bbd0f5 */ > +ra11 =3D -1.07812992258382800318665248311522624e+07L, /* 0xc0164904, 0x= e673a113, 0x35d7f079, 0xe13701f3 */ > +ra12 =3D -4.83545565681708642630419905537756076e+06L, /* 0xc0152721, 0x= fea094a8, 0x869eb39d, 0x413d6f13 */ > +ra13 =3D -1.23956521201673964822976917356685286e+06L, /* 0xc0132ea0, 0x= d3646baa, 0x2fe62b0d, 0xbae5ce85 */ > +ra14 =3D -1.62289333553652417591275333240371812e+05L, /* 0xc0103cf8, 0x= aab1e2d6, 0x4c25e014, 0x248d76ab */ > +ra15 =3D -8.82890392601176969729168894389833110e+03L, /* 0xc00c13e7, 0x= 3b3d8f94, 0x6fbda6f6, 0xe7049a82 */ > +ra16 =3D -1.22591866337261720023681535568334619e+02L, /* 0xc005ea5e, 0x= 12358891, 0xcfa712c5, 0x77f050d4 */ > +sa1 =3D 6.44508918884710829371852723353794047e+01L, /* 0x400501cd, 0x= b69a6c0f, 0x5716de14, 0x47161af6 */ > +sa2 =3D 1.76118475473171481523704824327358534e+03L, /* 0x4009b84b, 0x= d305829f, 0xc4c771b0, 0xbf1f7f9b */ > +sa3 =3D 2.69448346969488374857087646131950188e+04L, /* 0x400da503, 0x= 56bacc05, 0x4fdba68d, 0x2cca27e6 */ > +sa4 =3D 2.56826633369941456778326497384543763e+05L, /* 0x4010f59d, 0x= 51124428, 0x69c41de6, 0xbd0d5753 */ > +sa5 =3D 1.60647413092257206847700054645905859e+06L, /* 0x40138834, 0x= a2184244, 0x557a1bed, 0x68c9d556 */ > +sa6 =3D 6.76963075165099718574753447122393797e+06L, /* 0x40159d2f, 0x= 7b01b0cc, 0x8bac9e95, 0x5d35d56e */ > +sa7 =3D 1.94295690905361884290986932493647741e+07L, /* 0x40172878, 0x= c1172d61, 0x3068501e, 0x2f3c71da */ > +sa8 =3D 3.79774781017759149060839255547073541e+07L, /* 0x401821be, 0x= c30d06fe, 0x410563d7, 0x032111fd */ > +sa9 =3D 5.00659831846029484248302236457727397e+07L, /* 0x40187df9, 0x= 1f97a111, 0xc51d6ac2, 0x4b389793 */ > +sa10 =3D 4.36486287620506484276130525941972541e+07L, /* 0x40184d03, 0x= 3a618ae0, 0x2a723357, 0xfa45c60a */ > +sa11 =3D 2.43779678791333894255510508253951934e+07L, /* 0x401773fa, 0x= 6fe10ee2, 0xc467850d, 0xc6b7ff30 */ > +sa12 =3D 8.30732360384443202039372372212966542e+06L, /* 0x4015fb09, 0x= ee6a5631, 0xdd98de7e, 0x8b00461a */ > +sa13 =3D 1.60160846942050515734192397495105693e+06L, /* 0x40138704, 0x= 8782bf13, 0x5b8fb315, 0xa898abe5 */ > +sa14 =3D 1.54255505242533291014555153757001825e+05L, /* 0x40102d47, 0x= c0abc98e, 0x843c9490, 0xb4352440 */ > +sa15 =3D 5.87949220002375547561467275493888824e+03L, /* 0x400b6f77, 0x= e00d21d1, 0xec4d41e8, 0x2f8e1673 */ > +sa16 =3D 4.97272976346793193860385983372237710e+01L; /* 0x40048dd1, 0x= 816c1b3f, 0x24f540a6, 0x4cfe03cc */ > +/* > + * Domain [2.85715,9], range ~[-7.886e-37,7.918e-37]: > + * |log(x*erfc(x)) + x**2 + 0.5625 - rb(x)/sb(x)| < 2**-120 > + */ > +static const long double > +rb0 =3D -9.86494292470008707171371994479162369e-3L, /* 0xbff84341, 0x23= 9e86f4, 0x2f57e561, 0xf4469360 */ > +rb1 =3D -1.57047326624110727986326503729442830L, /* 0xbfff920a, 0x89= 35bf73, 0x8803b894, 0x4656482d */ > +rb2 =3D -1.03228196364885474342132255440317065e2L, /* 0xc0059ce9, 0xac= 4ed0ff, 0x2cff0ff7, 0x5e70d1ab */ > +rb3 =3D -3.74000570653418227179358710865224376e3L, /* 0xc00ad380, 0x2e= bf7835, 0xf6b07ed2, 0x861242f7 */ > +rb4 =3D -8.35435477739098044190860390632813956e4L, /* 0xc00f4657, 0x8c= 3ae934, 0x3647d7b3, 0x80e76fb7 */ > +rb5 =3D -1.21398672055223642118716640216747152e6L, /* 0xc0132862, 0x2b= 8761c8, 0x27d18c0f, 0x137c9463 */ > +rb6 =3D -1.17669175877248796101665344873273970e7L, /* 0xc0166719, 0x0b= 2cea46, 0x81f14174, 0x11602ea5 */ > +rb7 =3D -7.66108006086998253606773064264599615e7L, /* 0xc019243f, 0x3c= 26f4f0, 0x1cc05241, 0x3b953728 */ > +rb8 =3D -3.32547117558141845968704725353130804e8L, /* 0xc01b3d24, 0x42= d8ee26, 0x24ef6f3b, 0x604a8c65 */ > +rb9 =3D -9.41561252426350696802167711221739746e8L, /* 0xc01cc0f8, 0xad= 23692a, 0x8ddb2310, 0xe9937145 */ > +rb10 =3D -1.67157110805390944549427329626281063e9L, /* 0xc01d8e88, 0x9a= 903734, 0x09a55fa3, 0xd205c903 */ > +rb11 =3D -1.74339631004410841337645931421427373e9L, /* 0xc01d9fa8, 0x77= 582d2a, 0xc183b8ab, 0x7e00cb05 */ > +rb12 =3D -9.57655233596934915727573141357471703e8L, /* 0xc01cc8a5, 0x46= 0cc685, 0xd0271fa0, 0x6a70e3da */ > +rb13 =3D -2.26320062731339353035254704082495066e8L, /* 0xc01aafab, 0xd7= d76721, 0xc9720e11, 0x6a8bd489 */ > +rb14 =3D -1.42777302996263256686002973851837039e7L, /* 0xc016b3b8, 0xc4= 99689f, 0x2b88d965, 0xc32414f9 */ > +sb1 =3D 1.08512869705594540211033733976348506e2L, /* 0x4005b20d, 0x2d= b7528d, 0x00d20dcb, 0x858f6191 */ > +sb2 =3D 5.02757713761390460534494530537572834e3L, /* 0x400b3a39, 0x3b= f4a690, 0x3025d28d, 0xfd40a891 */ > +sb3 =3D 1.31019107205412870059331647078328430e5L, /* 0x400fffcb, 0x1b= 71d05e, 0x3b28361d, 0x2a3c3690 */ > +sb4 =3D 2.13021555152296846166736757455018030e6L, /* 0x40140409, 0x3c= 6984df, 0xc4491d7c, 0xb04aa08d */ > +sb5 =3D 2.26649105281820861953868568619768286e7L, /* 0x401759d6, 0xce= 8736f0, 0xf28ad037, 0x2a901e0c */ > +sb6 =3D 1.61071939490875921812318684143076081e8L, /* 0x401a3338, 0x68= 6fb541, 0x6bd27d06, 0x4f95c9ac */ > +sb7 =3D 7.66895673844301852676056750497991966e8L, /* 0x401c6daf, 0x31= cec121, 0x54699126, 0x4bd9bf9e */ > +sb8 =3D 2.41884450436101936436023058196042526e9L, /* 0x401e2059, 0x46= b0b8d7, 0x87b64cbf, 0x78bc296d */ > +sb9 =3D 4.92403055884071695093305291535107666e9L, /* 0x401f257e, 0xbe= 5ed739, 0x39e17346, 0xcadd2e55 */ > +sb10 =3D 6.18627786365587486459633615573786416e9L, /* 0x401f70bb, 0x1b= e7a7e7, 0x6a45b5ae, 0x607c70f0 */ > +sb11 =3D 4.45898013426501378097430226324743199e9L, /* 0x401f09c6, 0xa3= 2643d7, 0xf1724620, 0x9ea46c32 */ > +sb12 =3D 1.63006115763329848117160344854224975e9L, /* 0x401d84a3, 0x09= 96887f, 0x65a4f43b, 0x978c1d74 */ > +sb13 =3D 2.39216717012421697446304015847567721e8L, /* 0x401ac845, 0x09= a065c2, 0x30095da7, 0x9d72d6ae */ > +sb14 =3D 7.84837329009278694937250358810225609e6L; /* 0x4015df06, 0xd5= 290e15, 0x63031fac, 0x4d9c894c */ > +/* > + * Domain [9,108], range ~[-5.324e-38,5.340e-38]: > + * |log(x*erfc(x)) + x**2 + 0.5625 - r(x)/s(x)| < 2**-124 > + */ > +static const long double > +rc0 =3D -9.86494292470008707171367567652935673e-3L, /* 0xbff84341, 0x23= 9e86f4, 0x2f57e55b, 0x1aa10fd3 */ > +rc1 =3D -1.26229447747315096406518846411562266L, /* 0xbfff4325, 0xbb= 1aab28, 0xda395cd9, 0xfb861c15 */ > +rc2 =3D -6.13742634438922591780742637728666162e1L, /* 0xc004eafe, 0x7d= d51cd8, 0x3c7c5928, 0x751e50cf */ > +rc3 =3D -1.50455835478908280402912854338421517e3L, /* 0xc0097823, 0xbc= 15b9ab, 0x3d60745c, 0x523e80a5 */ > +rc4 =3D -2.04415631865861549920184039902945685e4L, /* 0xc00d3f66, 0x40= b3fc04, 0x5388f2ec, 0xb009e1f0 */ > +rc5 =3D -1.57625662981714582753490610560037638e5L, /* 0xc01033dc, 0xd4= dc95b6, 0xfd4da93b, 0xf355b4a9 */ > +rc6 =3D -6.73473451616752528402917538033283794e5L, /* 0xc01248d8, 0x2e= 73a4f9, 0xcded49c5, 0xfa3bfeb7 */ > +rc7 =3D -1.47433165421387483167186683764364857e6L, /* 0xc01367f1, 0xba= 77a8f7, 0xcfdd0dbb, 0x25d554b3 */ > +rc8 =3D -1.38811981807868828563794929997744139e6L, /* 0xc01352e5, 0x7d= 16d9ad, 0xbbdcbf38, 0x38fbc5ea */ > +rc9 =3D -3.59659700530831825640766479698155060e5L, /* 0xc0115f3a, 0xec= d57f45, 0x21f8ad6c, 0x910a5958 */ > +sc1 =3D 7.72730753022908298637508998072635696e1L, /* 0x40053517, 0xa1= 0d52bc, 0xdabb55b6, 0xbd0328cd */ > +sc2 =3D 2.36825757341694050500333261769082182e3L, /* 0x400a2808, 0x3e= 0a9b42, 0x82977842, 0x9c5de29e */ > +sc3 =3D 3.72210540173034735352888847134073099e4L, /* 0x400e22ca, 0x1b= a827ef, 0xac8390d7, 0x1fc39a41 */ > +sc4 =3D 3.24136032646418336712461033591393412e5L, /* 0x40113c8a, 0x02= 16e100, 0xc59d1e44, 0xf0e68d9d */ > +sc5 =3D 1.57836135851134393802505823370009175e6L, /* 0x40138157, 0x95= bc7664, 0x17575961, 0xdbe58eeb */ > +sc6 =3D 4.12881981392063738026679089714182355e6L, /* 0x4014f801, 0x9e= 82e8d2, 0xb8b3a70e, 0xfd84185d */ > +sc7 =3D 5.24438427289213488410596395361544142e6L, /* 0x40154017, 0x81= 177109, 0x2aa6c3b0, 0x1f106625 */ > +sc8 =3D 2.59909544563616121735963429710382149e6L, /* 0x40143d45, 0xbb= 90a9b1, 0x12bf9390, 0xa827a700 */ > +sc9 =3D 2.80930665169282501639651995082335693e5L; /* 0x40111258, 0xaa= 92222e, 0xa97e3216, 0xa237fa6c */ > + > +long double > +erfl(long double x) > +{ > + long double ax,R,S,P,Q,s,y,z,r; > + uint64_t lx, llx; > + int32_t i; > + uint16_t hx; > + > + EXTRACT_LDBL128_WORDS(hx, lx, llx, x); > + > + if((hx & 0x7fff) =3D=3D 0x7fff) { /* erfl(nan)=3Dnan */ > + i =3D (hx>>15)<<1; > + return (1-i)+one/x; /* erfl(+-inf)=3D+-1 */ > + } > + > + ax =3D fabsl(x); > + if(ax < 0.84375) { > + if(ax < 0x1p-40L) { > + if(ax < 0x1p-16373L) > + return (8*x+efx8*x)/8; /* avoid spurious underflow= */ > + return x + efx*x; > + } > + z =3D x*x; > + r =3D pp0+z*(pp1+z*(pp2+z*(pp3+z*(pp4+z*(pp5+z*(pp6+z*(pp7+ > + z*(pp8+z*pp9)))))))); > + s =3D one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*(qq5+z*(qq6+z*(qq7+ > + z*(qq8+z*qq9)))))))); > + y =3D r/s; > + return x + x*y; > + } > + if(ax < 1.25) { > + s =3D ax-one; > + P =3D pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*(pa6+s*(pa7+ > + s*(pa8+s*(pa9+s*(pa10+s*pa11)))))))))); > + Q =3D one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*(qa6+s*(qa7+ > + s*(qa8+s*(qa9+s*(qa10+s*(qa11+s*qa12))))))))))); > + if(x>=3D0) return (erx + P/Q); else return (-erx - P/Q); > + } > + if (ax >=3D 9) { /* inf>|x|>=3D 9 */ > + if(x>=3D0) return (one-tiny); else return (tiny-one); > + } > + s =3D one/(ax*ax); > + if(ax < 2.85715) { /* |x| < 2.85715 */ > + R=3Dra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(ra5+s*(ra6+s*(ra7+ > + s*(ra8+s*(ra9+s*(ra10+s*(ra11+s*(ra12+s*(ra13+s*(ra14+ > + s*(ra15+s*ra16))))))))))))))); > + S=3Done+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+ > + s*(sa8+s*(sa9+s*(sa10+s*(sa11+s*(sa12+s*(sa13+s*(sa14+ > + s*(sa15+s*sa16))))))))))))))); > + } else { /* |x| >=3D 2.85715 */ > + R=3Drb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*(rb6+s*(rb7+ > + s*(rb8+s*(rb9+s*(rb10+s*(rb11+s*(rb12+s*(rb13+ > + s*rb14))))))))))))); > + S=3Done+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*(sb7+ > + s*(sb8+s*(sb9+s*(sb10+s*(sb11+s*(sb12+s*(sb13+ > + s*sb14))))))))))))); > + } > + z =3D (float)ax; > + r =3D expl(-z*z-0.5625)*expl((z-ax)*(z+ax)+R/S); > + if(x>=3D0) return (one-r/ax); else return (r/ax-one); > +} > + > +long double > +erfcl(long double x) > +{ > + long double ax,R,S,P,Q,s,y,z,r; > + uint64_t lx, llx; > + uint16_t hx; > + > + EXTRACT_LDBL128_WORDS(hx, lx, llx, x); > + > + if((hx & 0x7fff) =3D=3D 0x7fff) { /* erfcl(nan)=3Dnan */ > + /* erfcl(+-inf)=3D0,2 */ > + return ((hx>>15)<<1)+one/x; > + } > + > + ax =3D fabsl(x); > + if(ax < 0.84375L) { > + if(ax < 0x1p-34L) > + return one-x; > + z =3D x*x; > + r =3D pp0+z*(pp1+z*(pp2+z*(pp3+z*(pp4+z*(pp5+z*(pp6+z*(pp7+ > + z*(pp8+z*pp9)))))))); > + s =3D one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*(qq5+z*(qq6+z*(qq7+ > + z*(qq8+z*qq9)))))))); > + y =3D r/s; > + if(ax < 0.25L) { /* x<1/4 */ > + return one-(x+x*y); > + } else { > + r =3D x*y; > + r +=3D (x-half); > + return half - r; > + } > + } > + if(ax < 1.25L) { > + s =3D ax-one; > + P =3D pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*(pa6+s*(pa7+ > + s*(pa8+s*(pa9+s*(pa10+s*pa11)))))))))); > + Q =3D one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*(qa6+s*(qa7+ > + s*(qa8+s*(qa9+s*(qa10+s*(qa11+s*qa12))))))))))); > + if(x>=3D0) { > + z =3D one-erx; return z - P/Q; > + } else { > + z =3D erx+P/Q; return one+z; > + } > + } > + > + if(ax < 108) { /* |x| < 108 */ > + s =3D one/(ax*ax); > + if(ax < 2.85715) { /* |x| < 2.85715 */ > + R=3Dra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(ra5+s*(ra6+s*(ra7+ > + s*(ra8+s*(ra9+s*(ra10+s*(ra11+s*(ra12+s*(ra13+s*(ra14+ > + s*(ra15+s*ra16))))))))))))))); > + S=3Done+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+ > + s*(sa8+s*(sa9+s*(sa10+s*(sa11+s*(sa12+s*(sa13+s*(sa14+ > + s*(sa15+s*sa16))))))))))))))); > + } else if(ax < 9) { > + R=3Drb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*(rb6+s*(rb7+ > + s*(rb8+s*(rb9+s*(rb10+s*(rb11+s*(rb12+s*(rb13+ > + s*rb14))))))))))))); > + S=3Done+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*(sb7+ > + s*(sb8+s*(sb9+s*(sb10+s*(sb11+s*(sb12+s*(sb13+ > + s*sb14))))))))))))); > + } else { > + if(x < -9) return two-tiny; /* x < -9 */ > + R=3Drc0+s*(rc1+s*(rc2+s*(rc3+s*(rc4+s*(rc5+s*(rc6+s*(rc7+ > + s*(rc8+s*rc9)))))))); > + S=3Done+s*(sc1+s*(sc2+s*(sc3+s*(sc4+s*(sc5+s*(sc6+s*(sc7+ > + s*(sc8+s*sc9)))))))); > + } > + z =3D (float)ax; > + r =3D expl(-z*z-0.5625)*expl((z-ax)*(z+ax)+R/S); > + if(x>0) return r/ax; else return two-r/ax; > + } else { > + if(x>0) return tiny*tiny; else return two-tiny; > + } > +} > diff --git a/newlib/libm/ld128/s_exp2l.c b/newlib/libm/ld128/s_exp2l.c > new file mode 100644 > index 000000000..ee3d2c782 > --- /dev/null > +++ b/newlib/libm/ld128/s_exp2l.c > @@ -0,0 +1,429 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2005-2008 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > +#include > + > +#include "fpmath.h" > +#include "math.h" > + > +#define TBLBITS 7 > +#define TBLSIZE (1 << TBLBITS) > + > +#define BIAS (LDBL_MAX_EXP - 1) > +#define EXPMASK (BIAS + LDBL_MAX_EXP) > + > +static volatile long double > + huge =3D 0x1p10000L, > + twom10000 =3D 0x1p-10000L; > + > +static const long double > + P1 =3D 0x1.62e42fefa39ef35793c7673007e6p-1L, > + P2 =3D 0x1.ebfbdff82c58ea86f16b06ec9736p-3L, > + P3 =3D 0x1.c6b08d704a0bf8b33a762bad3459p-5L, > + P4 =3D 0x1.3b2ab6fba4e7729ccbbe0b4f3fc2p-7L, > + P5 =3D 0x1.5d87fe78a67311071dee13fd11d9p-10L, > + P6 =3D 0x1.430912f86c7876f4b663b23c5fe5p-13L; > + > +static const double > + P7 =3D 0x1.ffcbfc588b041p-17, > + P8 =3D 0x1.62c0223a5c7c7p-20, > + P9 =3D 0x1.b52541ff59713p-24, > + P10 =3D 0x1.e4cf56a391e22p-28, > + redux =3D 0x1.8p112 / TBLSIZE; > + > +static const long double tbl[TBLSIZE] =3D { > + 0x1.6a09e667f3bcc908b2fb1366dfeap-1L, > + 0x1.6c012750bdabeed76a99800f4edep-1L, > + 0x1.6dfb23c651a2ef220e2cbe1bc0d4p-1L, > + 0x1.6ff7df9519483cf87e1b4f3e1e98p-1L, > + 0x1.71f75e8ec5f73dd2370f2ef0b148p-1L, > + 0x1.73f9a48a58173bd5c9a4e68ab074p-1L, > + 0x1.75feb564267c8bf6e9aa33a489a8p-1L, > + 0x1.780694fde5d3f619ae02808592a4p-1L, > + 0x1.7a11473eb0186d7d51023f6ccb1ap-1L, > + 0x1.7c1ed0130c1327c49334459378dep-1L, > + 0x1.7e2f336cf4e62105d02ba1579756p-1L, > + 0x1.80427543e1a11b60de67649a3842p-1L, > + 0x1.82589994cce128acf88afab34928p-1L, > + 0x1.8471a4623c7acce52f6b97c6444cp-1L, > + 0x1.868d99b4492ec80e41d90ac2556ap-1L, > + 0x1.88ac7d98a669966530bcdf2d4cc0p-1L, > + 0x1.8ace5422aa0db5ba7c55a192c648p-1L, > + 0x1.8cf3216b5448bef2aa1cd161c57ap-1L, > + 0x1.8f1ae991577362b982745c72eddap-1L, > + 0x1.9145b0b91ffc588a61b469f6b6a0p-1L, > + 0x1.93737b0cdc5e4f4501c3f2540ae8p-1L, > + 0x1.95a44cbc8520ee9b483695a0e7fep-1L, > + 0x1.97d829fde4e4f8b9e920f91e8eb6p-1L, > + 0x1.9a0f170ca07b9ba3109b8c467844p-1L, > + 0x1.9c49182a3f0901c7c46b071f28dep-1L, > + 0x1.9e86319e323231824ca78e64c462p-1L, > + 0x1.a0c667b5de564b29ada8b8cabbacp-1L, > + 0x1.a309bec4a2d3358c171f770db1f4p-1L, > + 0x1.a5503b23e255c8b424491caf88ccp-1L, > + 0x1.a799e1330b3586f2dfb2b158f31ep-1L, > + 0x1.a9e6b5579fdbf43eb243bdff53a2p-1L, > + 0x1.ac36bbfd3f379c0db966a3126988p-1L, > + 0x1.ae89f995ad3ad5e8734d17731c80p-1L, > + 0x1.b0e07298db66590842acdfc6fb4ep-1L, > + 0x1.b33a2b84f15faf6bfd0e7bd941b0p-1L, > + 0x1.b59728de559398e3881111648738p-1L, > + 0x1.b7f76f2fb5e46eaa7b081ab53ff6p-1L, > + 0x1.ba5b030a10649840cb3c6af5b74cp-1L, > + 0x1.bcc1e904bc1d2247ba0f45b3d06cp-1L, > + 0x1.bf2c25bd71e088408d7025190cd0p-1L, > + 0x1.c199bdd85529c2220cb12a0916bap-1L, > + 0x1.c40ab5fffd07a6d14df820f17deap-1L, > + 0x1.c67f12e57d14b4a2137fd20f2a26p-1L, > + 0x1.c8f6d9406e7b511acbc48805c3f6p-1L, > + 0x1.cb720dcef90691503cbd1e949d0ap-1L, > + 0x1.cdf0b555dc3f9c44f8958fac4f12p-1L, > + 0x1.d072d4a07897b8d0f22f21a13792p-1L, > + 0x1.d2f87080d89f18ade123989ea50ep-1L, > + 0x1.d5818dcfba48725da05aeb66dff8p-1L, > + 0x1.d80e316c98397bb84f9d048807a0p-1L, > + 0x1.da9e603db3285708c01a5b6d480cp-1L, > + 0x1.dd321f301b4604b695de3c0630c0p-1L, > + 0x1.dfc97337b9b5eb968cac39ed284cp-1L, > + 0x1.e264614f5a128a12761fa17adc74p-1L, > + 0x1.e502ee78b3ff6273d130153992d0p-1L, > + 0x1.e7a51fbc74c834b548b2832378a4p-1L, > + 0x1.ea4afa2a490d9858f73a18f5dab4p-1L, > + 0x1.ecf482d8e67f08db0312fb949d50p-1L, > + 0x1.efa1bee615a27771fd21a92dabb6p-1L, > + 0x1.f252b376bba974e8696fc3638f24p-1L, > + 0x1.f50765b6e4540674f84b762861a6p-1L, > + 0x1.f7bfdad9cbe138913b4bfe72bd78p-1L, > + 0x1.fa7c1819e90d82e90a7e74b26360p-1L, > + 0x1.fd3c22b8f71f10975ba4b32bd006p-1L, > + 0x1.0000000000000000000000000000p+0L, > + 0x1.0163da9fb33356d84a66ae336e98p+0L, > + 0x1.02c9a3e778060ee6f7caca4f7a18p+0L, > + 0x1.04315e86e7f84bd738f9a20da442p+0L, > + 0x1.059b0d31585743ae7c548eb68c6ap+0L, > + 0x1.0706b29ddf6ddc6dc403a9d87b1ep+0L, > + 0x1.0874518759bc808c35f25d942856p+0L, > + 0x1.09e3ecac6f3834521e060c584d5cp+0L, > + 0x1.0b5586cf9890f6298b92b7184200p+0L, > + 0x1.0cc922b7247f7407b705b893dbdep+0L, > + 0x1.0e3ec32d3d1a2020742e4f8af794p+0L, > + 0x1.0fb66affed31af232091dd8a169ep+0L, > + 0x1.11301d0125b50a4ebbf1aed9321cp+0L, > + 0x1.12abdc06c31cbfb92bad324d6f84p+0L, > + 0x1.1429aaea92ddfb34101943b2588ep+0L, > + 0x1.15a98c8a58e512480d573dd562aep+0L, > + 0x1.172b83c7d517adcdf7c8c50eb162p+0L, > + 0x1.18af9388c8de9bbbf70b9a3c269cp+0L, > + 0x1.1a35beb6fcb753cb698f692d2038p+0L, > + 0x1.1bbe084045cd39ab1e72b442810ep+0L, > + 0x1.1d4873168b9aa7805b8028990be8p+0L, > + 0x1.1ed5022fcd91cb8819ff61121fbep+0L, > + 0x1.2063b88628cd63b8eeb0295093f6p+0L, > + 0x1.21f49917ddc962552fd29294bc20p+0L, > + 0x1.2387a6e75623866c1fadb1c159c0p+0L, > + 0x1.251ce4fb2a63f3582ab7de9e9562p+0L, > + 0x1.26b4565e27cdd257a673281d3068p+0L, > + 0x1.284dfe1f5638096cf15cf03c9fa0p+0L, > + 0x1.29e9df51fdee12c25d15f5a25022p+0L, > + 0x1.2b87fd0dad98ffddea46538fca24p+0L, > + 0x1.2d285a6e4030b40091d536d0733ep+0L, > + 0x1.2ecafa93e2f5611ca0f45d5239a4p+0L, > + 0x1.306fe0a31b7152de8d5a463063bep+0L, > + 0x1.32170fc4cd8313539cf1c3009330p+0L, > + 0x1.33c08b26416ff4c9c8610d96680ep+0L, > + 0x1.356c55f929ff0c94623476373be4p+0L, > + 0x1.371a7373aa9caa7145502f45452ap+0L, > + 0x1.38cae6d05d86585a9cb0d9bed530p+0L, > + 0x1.3a7db34e59ff6ea1bc9299e0a1fep+0L, > + 0x1.3c32dc313a8e484001f228b58cf0p+0L, > + 0x1.3dea64c12342235b41223e13d7eep+0L, > + 0x1.3fa4504ac801ba0bf701aa417b9cp+0L, > + 0x1.4160a21f72e29f84325b8f3dbacap+0L, > + 0x1.431f5d950a896dc704439410b628p+0L, > + 0x1.44e086061892d03136f409df0724p+0L, > + 0x1.46a41ed1d005772512f459229f0ap+0L, > + 0x1.486a2b5c13cd013c1a3b69062f26p+0L, > + 0x1.4a32af0d7d3de672d8bcf46f99b4p+0L, > + 0x1.4bfdad5362a271d4397afec42e36p+0L, > + 0x1.4dcb299fddd0d63b36ef1a9e19dep+0L, > + 0x1.4f9b2769d2ca6ad33d8b69aa0b8cp+0L, > + 0x1.516daa2cf6641c112f52c84d6066p+0L, > + 0x1.5342b569d4f81df0a83c49d86bf4p+0L, > + 0x1.551a4ca5d920ec52ec620243540cp+0L, > + 0x1.56f4736b527da66ecb004764e61ep+0L, > + 0x1.58d12d497c7fd252bc2b7343d554p+0L, > + 0x1.5ab07dd48542958c93015191e9a8p+0L, > + 0x1.5c9268a5946b701c4b1b81697ed4p+0L, > + 0x1.5e76f15ad21486e9be4c20399d12p+0L, > + 0x1.605e1b976dc08b076f592a487066p+0L, > + 0x1.6247eb03a5584b1f0fa06fd2d9eap+0L, > + 0x1.6434634ccc31fc76f8714c4ee122p+0L, > + 0x1.66238825522249127d9e29b92ea2p+0L, > + 0x1.68155d44ca973081c57227b9f69ep+0L, > +}; > + > +static const float eps[TBLSIZE] =3D { > + -0x1.5c50p-101, > + -0x1.5d00p-106, > + 0x1.8e90p-102, > + -0x1.5340p-103, > + 0x1.1bd0p-102, > + -0x1.4600p-105, > + -0x1.7a40p-104, > + 0x1.d590p-102, > + -0x1.d590p-101, > + 0x1.b100p-103, > + -0x1.0d80p-105, > + 0x1.6b00p-103, > + -0x1.9f00p-105, > + 0x1.c400p-103, > + 0x1.e120p-103, > + -0x1.c100p-104, > + -0x1.9d20p-103, > + 0x1.a800p-108, > + 0x1.4c00p-106, > + -0x1.9500p-106, > + 0x1.6900p-105, > + -0x1.29d0p-100, > + 0x1.4c60p-103, > + 0x1.13a0p-102, > + -0x1.5b60p-103, > + -0x1.1c40p-103, > + 0x1.db80p-102, > + 0x1.91a0p-102, > + 0x1.dc00p-105, > + 0x1.44c0p-104, > + 0x1.9710p-102, > + 0x1.8760p-103, > + -0x1.a720p-103, > + 0x1.ed20p-103, > + -0x1.49c0p-102, > + -0x1.e000p-111, > + 0x1.86a0p-103, > + 0x1.2b40p-103, > + -0x1.b400p-108, > + 0x1.1280p-99, > + -0x1.02d8p-102, > + -0x1.e3d0p-103, > + -0x1.b080p-105, > + -0x1.f100p-107, > + -0x1.16c0p-105, > + -0x1.1190p-103, > + -0x1.a7d2p-100, > + 0x1.3450p-103, > + -0x1.67c0p-105, > + 0x1.4b80p-104, > + -0x1.c4e0p-103, > + 0x1.6000p-108, > + -0x1.3f60p-105, > + 0x1.93f0p-104, > + 0x1.5fe0p-105, > + 0x1.6f80p-107, > + -0x1.7600p-106, > + 0x1.21e0p-106, > + -0x1.3a40p-106, > + -0x1.40c0p-104, > + -0x1.9860p-105, > + -0x1.5d40p-108, > + -0x1.1d70p-106, > + 0x1.2760p-105, > + 0x0.0000p+0, > + 0x1.21e2p-104, > + -0x1.9520p-108, > + -0x1.5720p-106, > + -0x1.4810p-106, > + -0x1.be00p-109, > + 0x1.0080p-105, > + -0x1.5780p-108, > + -0x1.d460p-105, > + -0x1.6140p-105, > + 0x1.4630p-104, > + 0x1.ad50p-103, > + 0x1.82e0p-105, > + 0x1.1d3cp-101, > + 0x1.6100p-107, > + 0x1.ec30p-104, > + 0x1.f200p-108, > + 0x1.0b40p-103, > + 0x1.3660p-102, > + 0x1.d9d0p-103, > + -0x1.02d0p-102, > + 0x1.b070p-103, > + 0x1.b9c0p-104, > + -0x1.01c0p-103, > + -0x1.dfe0p-103, > + 0x1.1b60p-104, > + -0x1.ae94p-101, > + -0x1.3340p-104, > + 0x1.b3d8p-102, > + -0x1.6e40p-105, > + -0x1.3670p-103, > + 0x1.c140p-104, > + 0x1.1840p-101, > + 0x1.1ab0p-102, > + -0x1.a400p-104, > + 0x1.1f00p-104, > + -0x1.7180p-103, > + 0x1.4ce0p-102, > + 0x1.9200p-107, > + -0x1.54c0p-103, > + 0x1.1b80p-105, > + -0x1.1828p-101, > + 0x1.5720p-102, > + -0x1.a060p-100, > + 0x1.9160p-102, > + 0x1.a280p-104, > + 0x1.3400p-107, > + 0x1.2b20p-102, > + 0x1.7800p-108, > + 0x1.cfd0p-101, > + 0x1.2ef0p-102, > + -0x1.2760p-99, > + 0x1.b380p-104, > + 0x1.0048p-101, > + -0x1.60b0p-102, > + 0x1.a1ccp-100, > + -0x1.a640p-104, > + -0x1.08a0p-101, > + 0x1.7e60p-102, > + 0x1.22c0p-103, > + -0x1.7200p-106, > + 0x1.f0f0p-102, > + 0x1.eb4ep-99, > + 0x1.c6e0p-103, > +}; > + > +/* > + * exp2l(x): compute the base 2 exponential of x > + * > + * Accuracy: Peak error < 0.502 ulp. > + * > + * Method: (accurate tables) > + * > + * Reduce x: > + * x =3D 2**k + y, for integer k and |y| <=3D 1/2. > + * Thus we have exp2(x) =3D 2**k * exp2(y). > + * > + * Reduce y: > + * y =3D i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE. > + * Thus we have exp2(y) =3D exp2(i/TBLSIZE) * exp2(z - eps[i]), > + * with |z - eps[i]| <=3D 2**-8 + 2**-98 for the table used. > + * > + * We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) vi= a > + * a degree-10 minimax polynomial with maximum error under 2**-120. > + * The values in exp2t[] and eps[] are chosen such that > + * exp2t[i] =3D exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset= such > + * that exp2t[i] is accurate to 2**-122. > + * > + * Note that the range of i is +-TBLSIZE/2, so we actually index the t= ables > + * by i0 =3D i + TBLSIZE/2. > + * > + * This method is due to Gal, with many details due to Gal and Bacheli= s: > + * > + * Gal, S. and Bachelis, B. An Accurate Elementary Mathematical Libra= ry > + * for the IEEE Floating Point Standard. TOMS 17(1), 26-46 (1991). > + */ > +long double > +exp2l(long double x) > +{ > + union IEEEl2bits u, v; > + long double r, t, twopk, twopkp10000, z; > + uint32_t hx, ix, i0; > + int k; > + > + u.e =3D x; > + > + /* Filter out exceptional cases. */ > + hx =3D u.xbits.expsign; > + ix =3D hx & EXPMASK; > + if (ix >=3D BIAS + 14) { /* |x| >=3D 16384 */ > + if (ix =3D=3D BIAS + LDBL_MAX_EXP) { > + if (u.xbits.manh !=3D 0 > + || u.xbits.manl !=3D 0 > + || (hx & 0x8000) =3D=3D 0) > + return (x + x); /* x is NaN or +Inf */ > + else > + return (0.0); /* x is -Inf */ > + } > + if (x >=3D 16384) > + return (huge * huge); /* overflow */ > + if (x <=3D -16495) > + return (twom10000 * twom10000); /* underflow */ > + } else if (ix <=3D BIAS - 115) { /* |x| < 0x1p-115 */ > + return (1.0 + x); > + } > + > + /* > + * Reduce x, computing z, i0, and k. The low bits of x + redux > + * contain the 16-bit integer part of the exponent (k) followed by > + * TBLBITS fractional bits (i0). We use bit tricks to extract these > + * as integers, then set z to the remainder. > + * > + * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8. > + * Then the low-order word of x + redux is 0x000abc12, > + * We split this into k =3D 0xabc and i0 =3D 0x12 (adjusted to > + * index into the table), then we compute z =3D 0x0.003456p0. > + * > + * XXX If the exponent is negative, the computation of k depends on > + * '>>' doing sign extension. > + */ > + u.e =3D x + redux; > + i0 =3D (u.bits.manl & 0xffffffff) + TBLSIZE / 2; > + k =3D (int)i0 >> TBLBITS; > + i0 =3D i0 & (TBLSIZE - 1); > + u.e -=3D redux; > + z =3D x - u.e; > + v.xbits.manh =3D 0; > + v.xbits.manl =3D 0; > + if (k >=3D LDBL_MIN_EXP) { > + v.xbits.expsign =3D LDBL_MAX_EXP - 1 + k; > + twopk =3D v.e; > + } else { > + v.xbits.expsign =3D LDBL_MAX_EXP - 1 + k + 10000; > + twopkp10000 =3D v.e; > + } > + > + /* Compute r =3D exp2(y) =3D exp2t[i0] * p(z - eps[i]). */ > + t =3D tbl[i0]; /* exp2t[i0] */ > + z -=3D eps[i0]; /* eps[i0] */ > + r =3D t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * (P5 + z *= (P6 > + + z * (P7 + z * (P8 + z * (P9 + z * P10))))))))); > + > + /* Scale by 2**k. */ > + if(k >=3D LDBL_MIN_EXP) { > + if (k =3D=3D LDBL_MAX_EXP) > + return (r * 2.0 * 0x1p16383L); > + return (r * twopk); > + } else { > + return (r * twopkp10000 * twom10000); > + } > +} > diff --git a/newlib/libm/ld128/s_expl.c b/newlib/libm/ld128/s_expl.c > new file mode 100644 > index 000000000..5b786af49 > --- /dev/null > +++ b/newlib/libm/ld128/s_expl.c > @@ -0,0 +1,326 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2009-2013 Steven G. Kargl > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice unmodified, this list of conditions, and the following > + * disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + * > + * Optimized by Bruce D. Evans. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * ld128 version of s_expl.c. See ../ld80/s_expl.c for most comments. > + */ > + > +#include > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > +#include "k_expl.h" > + > +/* XXX Prevent compilers from erroneously constant folding these: */ > +static const volatile long double > +huge =3D 0x1p10000L, > +tiny =3D 0x1p-10000L; > + > +static const long double > +twom10000 =3D 0x1p-10000L; > + > +static const long double > +/* log(2**16384 - 0.5) rounded towards zero: */ > +/* log(2**16384 - 0.5 + 1) rounded towards zero for expm1l() is the same= : */ > +o_threshold =3D 11356.523406294143949491931077970763428L, > +/* log(2**(-16381-64-1)) rounded towards zero: */ > +u_threshold =3D -11433.462743336297878837243843452621503L; > + > +long double > +expl(long double x) > +{ > + union IEEEl2bits u; > + long double hi, lo, t, twopk; > + int k; > + uint16_t hx, ix; > + > + DOPRINT_START(&x); > + > + /* Filter out exceptional cases. */ > + u.e =3D x; > + hx =3D u.xbits.expsign; > + ix =3D hx & 0x7fff; > + if (ix >=3D BIAS + 13) { /* |x| >=3D 8192 or x is NaN */ > + if (ix =3D=3D BIAS + LDBL_MAX_EXP) { > + if (hx & 0x8000) /* x is -Inf or -NaN */ > + RETURNP(-1 / x); > + RETURNP(x + x); /* x is +Inf or +NaN */ > + } > + if (x > o_threshold) > + RETURNP(huge * huge); > + if (x < u_threshold) > + RETURNP(tiny * tiny); > + } else if (ix < BIAS - 114) { /* |x| < 0x1p-114 */ > + RETURN2P(1, x); /* 1 with inexact iff x !=3D 0 */ > + } > + > + ENTERI(); > + > + twopk =3D 1; > + __k_expl(x, &hi, &lo, &k); > + t =3D SUM2P(hi, lo); > + > + /* Scale by 2**k. */ > + /* > + * XXX sparc64 multiplication was so slow that scalbnl() is faster, > + * but performance on aarch64 and riscv hasn't yet been quantified. > + */ > + if (k >=3D LDBL_MIN_EXP) { > + if (k =3D=3D LDBL_MAX_EXP) > + RETURNI(t * 2 * 0x1p16383L); > + SET_LDBL_EXPSIGN(twopk, BIAS + k); > + RETURNI(t * twopk); > + } else { > + SET_LDBL_EXPSIGN(twopk, BIAS + k + 10000); > + RETURNI(t * twopk * twom10000); > + } > +} > + > +/* > + * Our T1 and T2 are chosen to be approximately the points where method > + * A and method B have the same accuracy. Tang's T1 and T2 are the > + * points where method A's accuracy changes by a full bit. For Tang, > + * this drop in accuracy makes method A immediately less accurate than > + * method B, but our larger INTERVALS makes method A 2 bits more > + * accurate so it remains the most accurate method significantly > + * closer to the origin despite losing the full bit in our extended > + * range for it. > + * > + * Split the interval [T1, T2] into two intervals [T1, T3] and [T3, T2]. > + * Setting T3 to 0 would require the |x| < 0x1p-113 condition to appear > + * in both subintervals, so set T3 =3D 2**-5, which places the condition > + * into the [T1, T3] interval. > + * > + * XXX we now do this more to (partially) balance the number of terms > + * in the C and D polys than to avoid checking the condition in both > + * intervals. > + * > + * XXX these micro-optimizations are excessive. > + */ > +static const double > +T1 =3D -0.1659, /* ~-30.625/128 * log(2) = */ > +T2 =3D 0.1659, /* ~30.625/128 * log(2) *= / > +T3 =3D 0.03125; > + > +/* > + * Domain [-0.1659, 0.03125], range ~[2.9134e-44, 1.8404e-37]: > + * |(exp(x)-1-x-x**2/2)/x - p(x)| < 2**-122.03 > + * > + * XXX none of the long double C or D coeffs except C10 is correctly pri= nted. > + * If you re-print their values in %.35Le format, the result is always > + * different. For example, the last 2 digits in C3 should be 59, not 67= . > + * 67 is apparently from rounding an extra-precision value to 36 decimal > + * places. > + */ > +static const long double > +C3 =3D 1.66666666666666666666666666666666667e-1L, > +C4 =3D 4.16666666666666666666666666666666645e-2L, > +C5 =3D 8.33333333333333333333333333333371638e-3L, > +C6 =3D 1.38888888888888888888888888891188658e-3L, > +C7 =3D 1.98412698412698412698412697235950394e-4L, > +C8 =3D 2.48015873015873015873015112487849040e-5L, > +C9 =3D 2.75573192239858906525606685484412005e-6L, > +C10 =3D 2.75573192239858906612966093057020362e-7L, > +C11 =3D 2.50521083854417203619031960151253944e-8L, > +C12 =3D 2.08767569878679576457272282566520649e-9L, > +C13 =3D 1.60590438367252471783548748824255707e-10L; > + > +/* > + * XXX this has 1 more coeff than needed. > + * XXX can start the double coeffs but not the double mults at C10. > + * With my coeffs (C10-C17 double; s =3D best_s): > + * Domain [-0.1659, 0.03125], range ~[-1.1976e-37, 1.1976e-37]: > + * |(exp(x)-1-x-x**2/2)/x - p(x)| ~< 2**-122.65 > + */ > +static const double > +C14 =3D 1.1470745580491932e-11, /* 0x1.93974a81dae30p-37= */ > +C15 =3D 7.6471620181090468e-13, /* 0x1.ae7f3820adab1p-41= */ > +C16 =3D 4.7793721460260450e-14, /* 0x1.ae7cd18a18eacp-45= */ > +C17 =3D 2.8074757356658877e-15, /* 0x1.949992a1937d9p-49= */ > +C18 =3D 1.4760610323699476e-16; /* 0x1.545b43aabfbcdp-53= */ > + > +/* > + * Domain [0.03125, 0.1659], range ~[-2.7676e-37, -1.0367e-38]: > + * |(exp(x)-1-x-x**2/2)/x - p(x)| < 2**-121.44 > + */ > +static const long double > +D3 =3D 1.66666666666666666666666666666682245e-1L, > +D4 =3D 4.16666666666666666666666666634228324e-2L, > +D5 =3D 8.33333333333333333333333364022244481e-3L, > +D6 =3D 1.38888888888888888888887138722762072e-3L, > +D7 =3D 1.98412698412698412699085805424661471e-4L, > +D8 =3D 2.48015873015873015687993712101479612e-5L, > +D9 =3D 2.75573192239858944101036288338208042e-6L, > +D10 =3D 2.75573192239853161148064676533754048e-7L, > +D11 =3D 2.50521083855084570046480450935267433e-8L, > +D12 =3D 2.08767569819738524488686318024854942e-9L, > +D13 =3D 1.60590442297008495301927448122499313e-10L; > + > +/* > + * XXX this has 1 more coeff than needed. > + * XXX can start the double coeffs but not the double mults at D11. > + * With my coeffs (D11-D16 double): > + * Domain [0.03125, 0.1659], range ~[-1.1980e-37, 1.1980e-37]: > + * |(exp(x)-1-x-x**2/2)/x - p(x)| ~< 2**-122.65 > + */ > +static const double > +D14 =3D 1.1470726176204336e-11, /* 0x1.93971dc395d9ep-37= */ > +D15 =3D 7.6478532249581686e-13, /* 0x1.ae892e3D16fcep-41= */ > +D16 =3D 4.7628892832607741e-14, /* 0x1.ad00Dfe41feccp-45= */ > +D17 =3D 3.0524857220358650e-15; /* 0x1.D7e8d886Df921p-49= */ > + > +long double > +expm1l(long double x) > +{ > + union IEEEl2bits u, v; > + long double hx2_hi, hx2_lo, q, r, r1, t, twomk, twopk, x_hi; > + long double x_lo, x2; > + double dr, dx, fn, r2; > + int k, n, n2; > + uint16_t hx, ix; > + > + DOPRINT_START(&x); > + > + /* Filter out exceptional cases. */ > + u.e =3D x; > + hx =3D u.xbits.expsign; > + ix =3D hx & 0x7fff; > + if (ix >=3D BIAS + 7) { /* |x| >=3D 128 or x is NaN */ > + if (ix =3D=3D BIAS + LDBL_MAX_EXP) { > + if (hx & 0x8000) /* x is -Inf or -NaN */ > + RETURNP(-1 / x - 1); > + RETURNP(x + x); /* x is +Inf or +NaN */ > + } > + if (x > o_threshold) > + RETURNP(huge * huge); > + /* > + * expm1l() never underflows, but it must avoid > + * unrepresentable large negative exponents. We used a > + * much smaller threshold for large |x| above than in > + * expl() so as to handle not so large negative exponents > + * in the same way as large ones here. > + */ > + if (hx & 0x8000) /* x <=3D -128 */ > + RETURN2P(tiny, -1); /* good for x < -114ln2 - e= ps */ > + } > + > + ENTERI(); > + > + if (T1 < x && x < T2) { > + x2 =3D x * x; > + dx =3D x; > + > + if (x < T3) { > + if (ix < BIAS - 113) { /* |x| < 0x1p-113 */ > + /* x (rounded) with inexact if x !=3D 0: */ > + RETURNPI(x =3D=3D 0 ? x : > + (0x1p200 * x + fabsl(x)) * 0x1p-200); > + } > + q =3D x * x2 * C3 + x2 * x2 * (C4 + x * (C5 + x * (= C6 + > + x * (C7 + x * (C8 + x * (C9 + x * (C10 + > + x * (C11 + x * (C12 + x * (C13 + > + dx * (C14 + dx * (C15 + dx * (C16 + > + dx * (C17 + dx * C18)))))))))))))); > + } else { > + q =3D x * x2 * D3 + x2 * x2 * (D4 + x * (D5 + x * (= D6 + > + x * (D7 + x * (D8 + x * (D9 + x * (D10 + > + x * (D11 + x * (D12 + x * (D13 + > + dx * (D14 + dx * (D15 + dx * (D16 + > + dx * D17))))))))))))); > + } > + > + x_hi =3D (float)x; > + x_lo =3D x - x_hi; > + hx2_hi =3D x_hi * x_hi / 2; > + hx2_lo =3D x_lo * (x + x_hi) / 2; > + if (ix >=3D BIAS - 7) > + RETURN2PI(hx2_hi + x_hi, hx2_lo + x_lo + q); > + else > + RETURN2PI(x, hx2_lo + q + hx2_hi); > + } > + > + /* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */ > + fn =3D rnint((double)x * INV_L); > + n =3D irint(fn); > + n2 =3D (unsigned)n % INTERVALS; > + k =3D n >> LOG2_INTERVALS; > + r1 =3D x - fn * L1; > + r2 =3D fn * -L2; > + r =3D r1 + r2; > + > + /* Prepare scale factor. */ > + v.e =3D 1; > + v.xbits.expsign =3D BIAS + k; > + twopk =3D v.e; > + > + /* > + * Evaluate lower terms of > + * expl(endpoint[n2] + r1 + r2) =3D tbl[n2] * expl(r1 + r2). > + */ > + dr =3D r; > + q =3D r2 + r * r * (A2 + r * (A3 + r * (A4 + r * (A5 + r * (A6 + > + dr * (A7 + dr * (A8 + dr * (A9 + dr * A10)))))))); > + > + t =3D tbl[n2].lo + tbl[n2].hi; > + > + if (k =3D=3D 0) { > + t =3D SUM2P(tbl[n2].hi - 1, tbl[n2].lo * (r1 + 1) + t * q + > + tbl[n2].hi * r1); > + RETURNI(t); > + } > + if (k =3D=3D -1) { > + t =3D SUM2P(tbl[n2].hi - 2, tbl[n2].lo * (r1 + 1) + t * q + > + tbl[n2].hi * r1); > + RETURNI(t / 2); > + } > + if (k < -7) { > + t =3D SUM2P(tbl[n2].hi, tbl[n2].lo + t * (q + r1)); > + RETURNI(t * twopk - 1); > + } > + if (k > 2 * LDBL_MANT_DIG - 1) { > + t =3D SUM2P(tbl[n2].hi, tbl[n2].lo + t * (q + r1)); > + if (k =3D=3D LDBL_MAX_EXP) > + RETURNI(t * 2 * 0x1p16383L - 1); > + RETURNI(t * twopk - 1); > + } > + > + v.xbits.expsign =3D BIAS - k; > + twomk =3D v.e; > + > + if (k > LDBL_MANT_DIG - 1) > + t =3D SUM2P(tbl[n2].hi, tbl[n2].lo - twomk + t * (q + r1)); > + else > + t =3D SUM2P(tbl[n2].hi - twomk, tbl[n2].lo + t * (q + r1)); > + RETURNI(t * twopk); > +} > diff --git a/newlib/libm/ld128/s_logl.c b/newlib/libm/ld128/s_logl.c > new file mode 100644 > index 000000000..4774a271e > --- /dev/null > +++ b/newlib/libm/ld128/s_logl.c > @@ -0,0 +1,740 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2007-2013 Bruce D. Evans > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice unmodified, this list of conditions, and the following > + * disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/** > + * Implementation of the natural logarithm of x for 128-bit format. > + * > + * First decompose x into its base 2 representation: > + * > + * log(x) =3D log(X * 2**k), where X is in [1, 2) > + * =3D log(X) + k * log(2). > + * > + * Let X =3D X_i + e, where X_i is the center of one of the intervals > + * [-1.0/256, 1.0/256), [1.0/256, 3.0/256), .... [2.0-1.0/256, 2.0+1.0/2= 56) > + * and X is in this interval. Then > + * > + * log(X) =3D log(X_i + e) > + * =3D log(X_i * (1 + e / X_i)) > + * =3D log(X_i) + log(1 + e / X_i). > + * > + * The values log(X_i) are tabulated below. Let d =3D e / X_i and use > + * > + * log(1 + d) =3D p(d) > + * > + * where p(d) =3D d - 0.5*d*d + ... is a special minimax polynomial of > + * suitably high degree. > + * > + * To get sufficiently small roundoff errors, k * log(2), log(X_i), and > + * sometimes (if |k| is not large) the first term in p(d) must be evalua= ted > + * and added up in extra precision. Extra precision is not needed for t= he > + * rest of p(d). In the worst case when k =3D 0 and log(X_i) is 0, the = final > + * error is controlled mainly by the error in the second term in p(d). = The > + * error in this term itself is at most 0.5 ulps from the d*d operation = in > + * it. The error in this term relative to the first term is thus at mos= t > + * 0.5 * |-0.5| * |d| < 1.0/1024 ulps. We aim for an accumulated error = of > + * at most twice this at the point of the final rounding step. Thus the > + * final error should be at most 0.5 + 1.0/512 =3D 0.5020 ulps. Exhaust= ive > + * testing of a float variant of this function showed a maximum final er= ror > + * of 0.5008 ulps. Non-exhaustive testing of a double variant of this > + * function showed a maximum final error of 0.5078 ulps (near 1+1.0/256)= . > + * > + * We made the maximum of |d| (and thus the total relative error and the > + * degree of p(d)) small by using a large number of intervals. Using > + * centers of intervals instead of endpoints reduces this maximum by a > + * factor of 2 for a given number of intervals. p(d) is special only > + * in beginning with the Taylor coefficients 0 + 1*d, which tends to hap= pen > + * naturally. The most accurate minimax polynomial of a given degree mi= ght > + * be different, but then we wouldn't want it since we would have to do > + * extra work to avoid roundoff error (especially for P0*d instead of d)= . > + */ > + > +#ifdef DEBUG > +#include > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#ifndef NO_STRUCT_RETURN > +#define STRUCT_RETURN > +#endif > +#include "math_private.h" > + > +#if !defined(NO_UTAB) && !defined(NO_UTABL) > +#define USE_UTAB > +#endif > + > +/* > + * Domain [-0.005280, 0.004838], range ~[-1.1577e-37, 1.1582e-37]: > + * |log(1 + d)/d - p(d)| < 2**-122.7 > + */ > +static const long double > +P2 =3D -0.5L, > +P3 =3D 3.33333333333333333333333333333233795e-1L, /* 0x15555555555= 555555555555554d42.0p-114L */ > +P4 =3D -2.49999999999999999999999999941139296e-1L, /* -0x1ffffffffff= ffffffffffffdab14e.0p-115L */ > +P5 =3D 2.00000000000000000000000085468039943e-1L, /* 0x19999999999= 999999999a6d3567f4.0p-115L */ > +P6 =3D -1.66666666666666666666696142372698408e-1L, /* -0x15555555555= 555555567267a58e13.0p-115L */ > +P7 =3D 1.42857142857142857119522943477166120e-1L, /* 0x12492492492= 49248ed79a0ae434de.0p-115L */ > +P8 =3D -1.24999999999999994863289015033581301e-1L; /* -0x1ffffffffff= fffa13e91765e46140.0p-116L */ > +/* Double precision gives ~ 53 + log2(P9 * max(|d|)**8) ~=3D 120 bits. *= / > +static const double > +P9 =3D 1.1111111111111401e-1, /* 0x1c71c71c71c7ed.0p-56 */ > +P10 =3D -1.0000000000040135e-1, /* -0x199999999a0a92.0p-5= 6 */ > +P11 =3D 9.0909090728136258e-2, /* 0x1745d173962111.0p-5= 6 */ > +P12 =3D -8.3333318851855284e-2, /* -0x1555551722c7a3.0p-5= 6 */ > +P13 =3D 7.6928634666404178e-2, /* 0x13b1985204a4ae.0p-5= 6 */ > +P14 =3D -7.1626810078462499e-2; /* -0x12562276cdc5d0.0p-5= 6 */ > + > +static volatile const double zero =3D 0; > + > +#define INTERVALS 128 > +#define LOG2_INTERVALS 7 > +#define TSIZE (INTERVALS + 1) > +#define G(i) (T[(i)].G) > +#define F_hi(i) (T[(i)].F_hi) > +#define F_lo(i) (T[(i)].F_lo) > +#define ln2_hi F_hi(TSIZE - 1) > +#define ln2_lo F_lo(TSIZE - 1) > +#define E(i) (U[(i)].E) > +#define H(i) (U[(i)].H) > + > +static const struct { > + float G; /* 1/(1 + i/128) rounded to 8/9 bit= s */ > + float F_hi; /* log(1 / G_i) rounded (see below)= */ > + /* The compiler will insert 8 bytes of padding here. */ > + long double F_lo; /* next 113 bits for log(1 / G_i) *= / > +} T[TSIZE] =3D { > + /* > + * ln2_hi and each F_hi(i) are rounded to a number of bits that > + * makes F_hi(i) + dk*ln2_hi exact for all i and all dk. > + * > + * The last entry (for X just below 2) is used to define ln2_hi > + * and ln2_lo, to ensure that F_hi(i) and F_lo(i) cancel exactly > + * with dk*ln2_hi and dk*ln2_lo, respectively, when dk =3D -1. > + * This is needed for accuracy when x is just below 1. (To avoid > + * special cases, such x are "reduced" strangely to X just below > + * 2 and dk =3D -1, and then the exact cancellation is needed > + * because any the error from any non-exactness would be too > + * large). > + * > + * The relevant range of dk is [-16445, 16383]. The maximum number > + * of bits in F_hi(i) that works is very dependent on i but has > + * a minimum of 93. We only need about 12 bits in F_hi(i) for > + * it to provide enough extra precision. > + * > + * We round F_hi(i) to 24 bits so that it can have type float, > + * mainly to minimize the size of the table. Using all 24 bits > + * in a float for it automatically satisfies the above constraints. > + */ > + 0x800000.0p-23, 0, 0, > + 0xfe0000.0p-24, 0x8080ac.0p-30, -0x14ee431dae6674afa0c4bfe16e8fd.0= p-144L, > + 0xfc0000.0p-24, 0x8102b3.0p-29, -0x1db29ee2d83717be918e1119642ab.0= p-144L, > + 0xfa0000.0p-24, 0xc24929.0p-29, 0x1191957d173697cf302cc9476f561.0= p-143L, > + 0xf80000.0p-24, 0x820aec.0p-28, 0x13ce8888e02e78eba9b1113bc1c18.0= p-142L, > + 0xf60000.0p-24, 0xa33577.0p-28, -0x17a4382ce6eb7bfa509bec8da5f22.0= p-142L, > + 0xf48000.0p-24, 0xbc42cb.0p-28, -0x172a21161a107674986dcdca6709c.0= p-143L, > + 0xf30000.0p-24, 0xd57797.0p-28, -0x1e09de07cb958897a3ea46e84abb3.0= p-142L, > + 0xf10000.0p-24, 0xf7518e.0p-28, 0x1ae1eec1b036c484993c549c4bf40.0= p-151L, > + 0xef0000.0p-24, 0x8cb9df.0p-27, -0x1d7355325d560d9e9ab3d6ebab580.0= p-141L, > + 0xed8000.0p-24, 0x999ec0.0p-27, -0x1f9f02d256d5037108f4ec21e48cd.0= p-142L, > + 0xec0000.0p-24, 0xa6988b.0p-27, -0x16fc0a9d12c17a70f7a684c596b12.0= p-143L, > + 0xea0000.0p-24, 0xb80698.0p-27, 0x15d581c1e8da99ded322fb08b8462.0= p-141L, > + 0xe80000.0p-24, 0xc99af3.0p-27, -0x1535b3ba8f150ae09996d7bb4653e.0= p-143L, > + 0xe70000.0p-24, 0xd273b2.0p-27, 0x163786f5251aefe0ded34c8318f52.0= p-145L, > + 0xe50000.0p-24, 0xe442c0.0p-27, 0x1bc4b2368e32d56699c1799a244d4.0= p-144L, > + 0xe38000.0p-24, 0xf1b83f.0p-27, 0x1c6090f684e6766abceccab1d7174.0= p-141L, > + 0xe20000.0p-24, 0xff448a.0p-27, -0x1890aa69ac9f4215f93936b709efb.0= p-142L, > + 0xe08000.0p-24, 0x8673f6.0p-26, 0x1b9985194b6affd511b534b72a28e.0= p-140L, > + 0xdf0000.0p-24, 0x8d515c.0p-26, -0x1dc08d61c6ef1d9b2ef7e68680598.0= p-143L, > + 0xdd8000.0p-24, 0x943a9e.0p-26, -0x1f72a2dac729b3f46662238a9425a.0= p-142L, > + 0xdc0000.0p-24, 0x9b2fe6.0p-26, -0x1fd4dfd3a0afb9691aed4d5e3df94.0= p-140L, > + 0xda8000.0p-24, 0xa2315d.0p-26, -0x11b26121629c46c186384993e1c93.0= p-142L, > + 0xd90000.0p-24, 0xa93f2f.0p-26, 0x1286d633e8e5697dc6a402a56fce1.0= p-141L, > + 0xd78000.0p-24, 0xb05988.0p-26, 0x16128eba9367707ebfa540e45350c.0= p-144L, > + 0xd60000.0p-24, 0xb78094.0p-26, 0x16ead577390d31ef0f4c9d43f79b2.0= p-140L, > + 0xd50000.0p-24, 0xbc4c6c.0p-26, 0x151131ccf7c7b75e7d900b521c48d.0= p-141L, > + 0xd38000.0p-24, 0xc3890a.0p-26, -0x115e2cd714bd06508aeb00d2ae3e9.0= p-140L, > + 0xd20000.0p-24, 0xcad2d7.0p-26, -0x1847f406ebd3af80485c2f409633c.0= p-142L, > + 0xd10000.0p-24, 0xcfb620.0p-26, 0x1c2259904d686581799fbce0b5f19.0= p-141L, > + 0xcf8000.0p-24, 0xd71653.0p-26, 0x1ece57a8d5ae54f550444ecf8b995.0= p-140L, > + 0xce0000.0p-24, 0xde843a.0p-26, -0x1f109d4bc4595412b5d2517aaac13.0= p-141L, > + 0xcd0000.0p-24, 0xe37fde.0p-26, 0x1bc03dc271a74d3a85b5b43c0e727.0= p-141L, > + 0xcb8000.0p-24, 0xeb050c.0p-26, -0x1bf2badc0df841a71b79dd5645b46.0= p-145L, > + 0xca0000.0p-24, 0xf29878.0p-26, -0x18efededd89fbe0bcfbe6d6db9f66.0= p-147L, > + 0xc90000.0p-24, 0xf7ad6f.0p-26, 0x1373ff977baa6911c7bafcb4d84fb.0= p-141L, > + 0xc80000.0p-24, 0xfcc8e3.0p-26, 0x196766f2fb328337cc050c6d83b22.0= p-140L, > + 0xc68000.0p-24, 0x823f30.0p-25, 0x19bd076f7c434e5fcf1a212e2a91e.0= p-139L, > + 0xc58000.0p-24, 0x84d52c.0p-25, -0x1a327257af0f465e5ecab5f2a6f81.0= p-139L, > + 0xc40000.0p-24, 0x88bc74.0p-25, 0x113f23def19c5a0fe396f40f1dda9.0= p-141L, > + 0xc30000.0p-24, 0x8b5ae6.0p-25, 0x1759f6e6b37de945a049a962e66c6.0= p-139L, > + 0xc20000.0p-24, 0x8dfccb.0p-25, 0x1ad35ca6ed5147bdb6ddcaf59c425.0= p-141L, > + 0xc10000.0p-24, 0x90a22b.0p-25, 0x1a1d71a87deba46bae9827221dc98.0= p-139L, > + 0xbf8000.0p-24, 0x94a0d8.0p-25, -0x139e5210c2b730e28aba001a9b5e0.0= p-140L, > + 0xbe8000.0p-24, 0x974f16.0p-25, -0x18f6ebcff3ed72e23e13431adc4a5.0= p-141L, > + 0xbd8000.0p-24, 0x9a00f1.0p-25, -0x1aa268be39aab7148e8d80caa10b7.0= p-139L, > + 0xbc8000.0p-24, 0x9cb672.0p-25, -0x14c8815839c5663663d15faed7771.0= p-139L, > + 0xbb0000.0p-24, 0xa0cda1.0p-25, 0x1eaf46390dbb2438273918db7df5c.0= p-141L, > + 0xba0000.0p-24, 0xa38c6e.0p-25, 0x138e20d831f698298adddd7f32686.0= p-141L, > + 0xb90000.0p-24, 0xa64f05.0p-25, -0x1e8d3c41123615b147a5d47bc208f.0= p-142L, > + 0xb80000.0p-24, 0xa91570.0p-25, 0x1ce28f5f3840b263acb4351104631.0= p-140L, > + 0xb70000.0p-24, 0xabdfbb.0p-25, -0x186e5c0a42423457e22d8c650b355.0= p-139L, > + 0xb60000.0p-24, 0xaeadef.0p-25, -0x14d41a0b2a08a465dc513b13f567d.0= p-143L, > + 0xb50000.0p-24, 0xb18018.0p-25, 0x16755892770633947ffe651e7352f.0= p-139L, > + 0xb40000.0p-24, 0xb45642.0p-25, -0x16395ebe59b15228bfe8798d10ff0.0= p-142L, > + 0xb30000.0p-24, 0xb73077.0p-25, 0x1abc65c8595f088b61a335f5b688c.0= p-140L, > + 0xb20000.0p-24, 0xba0ec4.0p-25, -0x1273089d3dad88e7d353e9967d548.0= p-139L, > + 0xb10000.0p-24, 0xbcf133.0p-25, 0x10f9f67b1f4bbf45de06ecebfaf6d.0= p-139L, > + 0xb00000.0p-24, 0xbfd7d2.0p-25, -0x109fab904864092b34edda19a831e.0= p-140L, > + 0xaf0000.0p-24, 0xc2c2ac.0p-25, -0x1124680aa43333221d8a9b475a6ba.0= p-139L, > + 0xae8000.0p-24, 0xc439b3.0p-25, -0x1f360cc4710fbfe24b633f4e8d84d.0= p-140L, > + 0xad8000.0p-24, 0xc72afd.0p-25, -0x132d91f21d89c89c45003fc5d7807.0= p-140L, > + 0xac8000.0p-24, 0xca20a2.0p-25, -0x16bf9b4d1f8da8002f2449e174504.0= p-139L, > + 0xab8000.0p-24, 0xcd1aae.0p-25, 0x19deb5ce6a6a8717d5626e16acc7d.0= p-141L, > + 0xaa8000.0p-24, 0xd0192f.0p-25, 0x1a29fb48f7d3ca87dabf351aa41f4.0= p-139L, > + 0xaa0000.0p-24, 0xd19a20.0p-25, 0x1127d3c6457f9d79f51dcc73014c9.0= p-141L, > + 0xa90000.0p-24, 0xd49f6a.0p-25, -0x1ba930e486a0ac42d1bf9199188e7.0= p-141L, > + 0xa80000.0p-24, 0xd7a94b.0p-25, -0x1b6e645f31549dd1160bcc45c7e2c.0= p-139L, > + 0xa70000.0p-24, 0xdab7d0.0p-25, 0x1118a425494b610665377f15625b6.0= p-140L, > + 0xa68000.0p-24, 0xdc40d5.0p-25, 0x1966f24d29d3a2d1b2176010478be.0= p-140L, > + 0xa58000.0p-24, 0xdf566d.0p-25, -0x1d8e52eb2248f0c95dd83626d7333.0= p-142L, > + 0xa48000.0p-24, 0xe270ce.0p-25, -0x1ee370f96e6b67ccb006a5b9890ea.0= p-140L, > + 0xa40000.0p-24, 0xe3ffce.0p-25, 0x1d155324911f56db28da4d629d00a.0= p-140L, > + 0xa30000.0p-24, 0xe72179.0p-25, -0x1fe6e2f2f867d8f4d60c713346641.0= p-140L, > + 0xa20000.0p-24, 0xea4812.0p-25, 0x1b7be9add7f4d3b3d406b6cbf3ce5.0= p-140L, > + 0xa18000.0p-24, 0xebdd3d.0p-25, 0x1b3cfb3f7511dd73692609040ccc2.0= p-139L, > + 0xa08000.0p-24, 0xef0b5b.0p-25, -0x1220de1f7301901b8ad85c25afd09.0= p-139L, > + 0xa00000.0p-24, 0xf0a451.0p-25, -0x176364c9ac81cc8a4dfb804de6867.0= p-140L, > + 0x9f0000.0p-24, 0xf3da16.0p-25, 0x1eed6b9aafac8d42f78d3e65d3727.0= p-141L, > + 0x9e8000.0p-24, 0xf576e9.0p-25, 0x1d593218675af269647b783d88999.0= p-139L, > + 0x9d8000.0p-24, 0xf8b47c.0p-25, -0x13e8eb7da053e063714615f7cc91d.0= p-144L, > + 0x9d0000.0p-24, 0xfa553f.0p-25, 0x1c063259bcade02951686d5373aec.0= p-139L, > + 0x9c0000.0p-24, 0xfd9ac5.0p-25, 0x1ef491085fa3c1649349630531502.0= p-139L, > + 0x9b8000.0p-24, 0xff3f8c.0p-25, 0x1d607a7c2b8c5320619fb9433d841.0= p-139L, > + 0x9a8000.0p-24, 0x814697.0p-24, -0x12ad3817004f3f0bdff99f932b273.0= p-138L, > + 0x9a0000.0p-24, 0x821b06.0p-24, -0x189fc53117f9e54e78103a2bc1767.0= p-141L, > + 0x990000.0p-24, 0x83c5f8.0p-24, 0x14cf15a048907b7d7f47ddb45c5a3.0= p-139L, > + 0x988000.0p-24, 0x849c7d.0p-24, 0x1cbb1d35fb82873b04a9af1dd692c.0= p-138L, > + 0x978000.0p-24, 0x864ba6.0p-24, 0x1128639b814f9b9770d8cb6573540.0= p-138L, > + 0x970000.0p-24, 0x87244c.0p-24, 0x184733853300f002e836dfd47bd41.0= p-139L, > + 0x968000.0p-24, 0x87fdaa.0p-24, 0x109d23aef77dd5cd7cc94306fb3ff.0= p-140L, > + 0x958000.0p-24, 0x89b293.0p-24, -0x1a81ef367a59de2b41eeebd550702.0= p-138L, > + 0x950000.0p-24, 0x8a8e20.0p-24, -0x121ad3dbb2f45275c917a30df4ac9.0= p-138L, > + 0x948000.0p-24, 0x8b6a6a.0p-24, -0x1cfb981628af71a89df4e6df2e93b.0= p-139L, > + 0x938000.0p-24, 0x8d253a.0p-24, -0x1d21730ea76cfdec367828734cae5.0= p-139L, > + 0x930000.0p-24, 0x8e03c2.0p-24, 0x135cc00e566f76b87333891e0dec4.0= p-138L, > + 0x928000.0p-24, 0x8ee30d.0p-24, -0x10fcb5df257a263e3bf446c6e3f69.0= p-140L, > + 0x918000.0p-24, 0x90a3ee.0p-24, -0x16e171b15433d723a4c7380a448d8.0= p-139L, > + 0x910000.0p-24, 0x918587.0p-24, -0x1d050da07f3236f330972da2a7a87.0= p-139L, > + 0x908000.0p-24, 0x9267e7.0p-24, 0x1be03669a5268d21148c6002becd3.0= p-139L, > + 0x8f8000.0p-24, 0x942f04.0p-24, 0x10b28e0e26c336af90e00533323ba.0= p-139L, > + 0x8f0000.0p-24, 0x9513c3.0p-24, 0x1a1d820da57cf2f105a89060046aa.0= p-138L, > + 0x8e8000.0p-24, 0x95f950.0p-24, -0x19ef8f13ae3cf162409d8ea99d4c0.0= p-139L, > + 0x8e0000.0p-24, 0x96dfab.0p-24, -0x109e417a6e507b9dc10dac743ad7a.0= p-138L, > + 0x8d0000.0p-24, 0x98aed2.0p-24, 0x10d01a2c5b0e97c4990b23d9ac1f5.0= p-139L, > + 0x8c8000.0p-24, 0x9997a2.0p-24, -0x1d6a50d4b61ea74540bdd2aa99a42.0= p-138L, > + 0x8c0000.0p-24, 0x9a8145.0p-24, 0x1b3b190b83f9527e6aba8f2d783c1.0= p-138L, > + 0x8b8000.0p-24, 0x9b6bbf.0p-24, 0x13a69fad7e7abe7ba81c664c107e0.0= p-138L, > + 0x8b0000.0p-24, 0x9c5711.0p-24, -0x11cd12316f576aad348ae79867223.0= p-138L, > + 0x8a8000.0p-24, 0x9d433b.0p-24, 0x1c95c444b807a246726b304ccae56.0= p-139L, > + 0x898000.0p-24, 0x9f1e22.0p-24, -0x1b9c224ea698c2f9b47466d6123fe.0= p-139L, > + 0x890000.0p-24, 0xa00ce1.0p-24, 0x125ca93186cf0f38b4619a2483399.0= p-141L, > + 0x888000.0p-24, 0xa0fc80.0p-24, -0x1ee38a7bc228b3597043be78eaf49.0= p-139L, > + 0x880000.0p-24, 0xa1ed00.0p-24, -0x1a0db876613d204147dc69a07a649.0= p-138L, > + 0x878000.0p-24, 0xa2de62.0p-24, 0x193224e8516c008d3602a7b41c6e8.0= p-139L, > + 0x870000.0p-24, 0xa3d0a9.0p-24, 0x1fa28b4d2541aca7d5844606b2421.0= p-139L, > + 0x868000.0p-24, 0xa4c3d6.0p-24, 0x1c1b5760fb4571acbcfb03f16daf4.0= p-138L, > + 0x858000.0p-24, 0xa6acea.0p-24, 0x1fed5d0f65949c0a345ad743ae1ae.0= p-140L, > + 0x850000.0p-24, 0xa7a2d4.0p-24, 0x1ad270c9d749362382a7688479e24.0= p-140L, > + 0x848000.0p-24, 0xa899ab.0p-24, 0x199ff15ce532661ea9643a3a2d378.0= p-139L, > + 0x840000.0p-24, 0xa99171.0p-24, 0x1a19e15ccc45d257530a682b80490.0= p-139L, > + 0x838000.0p-24, 0xaa8a28.0p-24, -0x121a14ec532b35ba3e1f868fd0b5e.0= p-140L, > + 0x830000.0p-24, 0xab83d1.0p-24, 0x1aee319980bff3303dd481779df69.0= p-139L, > + 0x828000.0p-24, 0xac7e6f.0p-24, -0x18ffd9e3900345a85d2d86161742e.0= p-140L, > + 0x820000.0p-24, 0xad7a03.0p-24, -0x1e4db102ce29f79b026b64b42caa1.0= p-140L, > + 0x818000.0p-24, 0xae768f.0p-24, 0x17c35c55a04a82ab19f77652d977a.0= p-141L, > + 0x810000.0p-24, 0xaf7415.0p-24, 0x1448324047019b48d7b98c1cf7234.0= p-138L, > + 0x808000.0p-24, 0xb07298.0p-24, -0x1750ee3915a197e9c7359dd94152f.0= p-138L, > + 0x800000.0p-24, 0xb17218.0p-24, -0x105c610ca86c3898cff81a12a17e2.0= p-141L, > +}; > + > +#ifdef USE_UTAB > +static const struct { > + float H; /* 1 + i/INTERVALS (exact) */ > + float E; /* H(i) * G(i) - 1 (exact) */ > +} U[TSIZE] =3D { > + 0x800000.0p-23, 0, > + 0x810000.0p-23, -0x800000.0p-37, > + 0x820000.0p-23, -0x800000.0p-35, > + 0x830000.0p-23, -0x900000.0p-34, > + 0x840000.0p-23, -0x800000.0p-33, > + 0x850000.0p-23, -0xc80000.0p-33, > + 0x860000.0p-23, -0xa00000.0p-36, > + 0x870000.0p-23, 0x940000.0p-33, > + 0x880000.0p-23, 0x800000.0p-35, > + 0x890000.0p-23, -0xc80000.0p-34, > + 0x8a0000.0p-23, 0xe00000.0p-36, > + 0x8b0000.0p-23, 0x900000.0p-33, > + 0x8c0000.0p-23, -0x800000.0p-35, > + 0x8d0000.0p-23, -0xe00000.0p-33, > + 0x8e0000.0p-23, 0x880000.0p-33, > + 0x8f0000.0p-23, -0xa80000.0p-34, > + 0x900000.0p-23, -0x800000.0p-35, > + 0x910000.0p-23, 0x800000.0p-37, > + 0x920000.0p-23, 0x900000.0p-35, > + 0x930000.0p-23, 0xd00000.0p-35, > + 0x940000.0p-23, 0xe00000.0p-35, > + 0x950000.0p-23, 0xc00000.0p-35, > + 0x960000.0p-23, 0xe00000.0p-36, > + 0x970000.0p-23, -0x800000.0p-38, > + 0x980000.0p-23, -0xc00000.0p-35, > + 0x990000.0p-23, -0xd00000.0p-34, > + 0x9a0000.0p-23, 0x880000.0p-33, > + 0x9b0000.0p-23, 0xe80000.0p-35, > + 0x9c0000.0p-23, -0x800000.0p-35, > + 0x9d0000.0p-23, 0xb40000.0p-33, > + 0x9e0000.0p-23, 0x880000.0p-34, > + 0x9f0000.0p-23, -0xe00000.0p-35, > + 0xa00000.0p-23, 0x800000.0p-33, > + 0xa10000.0p-23, -0x900000.0p-36, > + 0xa20000.0p-23, -0xb00000.0p-33, > + 0xa30000.0p-23, -0xa00000.0p-36, > + 0xa40000.0p-23, 0x800000.0p-33, > + 0xa50000.0p-23, -0xf80000.0p-35, > + 0xa60000.0p-23, 0x880000.0p-34, > + 0xa70000.0p-23, -0x900000.0p-33, > + 0xa80000.0p-23, -0x800000.0p-35, > + 0xa90000.0p-23, 0x900000.0p-34, > + 0xaa0000.0p-23, 0xa80000.0p-33, > + 0xab0000.0p-23, -0xac0000.0p-34, > + 0xac0000.0p-23, -0x800000.0p-37, > + 0xad0000.0p-23, 0xf80000.0p-35, > + 0xae0000.0p-23, 0xf80000.0p-34, > + 0xaf0000.0p-23, -0xac0000.0p-33, > + 0xb00000.0p-23, -0x800000.0p-33, > + 0xb10000.0p-23, -0xb80000.0p-34, > + 0xb20000.0p-23, -0x800000.0p-34, > + 0xb30000.0p-23, -0xb00000.0p-35, > + 0xb40000.0p-23, -0x800000.0p-35, > + 0xb50000.0p-23, -0xe00000.0p-36, > + 0xb60000.0p-23, -0x800000.0p-35, > + 0xb70000.0p-23, -0xb00000.0p-35, > + 0xb80000.0p-23, -0x800000.0p-34, > + 0xb90000.0p-23, -0xb80000.0p-34, > + 0xba0000.0p-23, -0x800000.0p-33, > + 0xbb0000.0p-23, -0xac0000.0p-33, > + 0xbc0000.0p-23, 0x980000.0p-33, > + 0xbd0000.0p-23, 0xbc0000.0p-34, > + 0xbe0000.0p-23, 0xe00000.0p-36, > + 0xbf0000.0p-23, -0xb80000.0p-35, > + 0xc00000.0p-23, -0x800000.0p-33, > + 0xc10000.0p-23, 0xa80000.0p-33, > + 0xc20000.0p-23, 0x900000.0p-34, > + 0xc30000.0p-23, -0x800000.0p-35, > + 0xc40000.0p-23, -0x900000.0p-33, > + 0xc50000.0p-23, 0x820000.0p-33, > + 0xc60000.0p-23, 0x800000.0p-38, > + 0xc70000.0p-23, -0x820000.0p-33, > + 0xc80000.0p-23, 0x800000.0p-33, > + 0xc90000.0p-23, -0xa00000.0p-36, > + 0xca0000.0p-23, -0xb00000.0p-33, > + 0xcb0000.0p-23, 0x840000.0p-34, > + 0xcc0000.0p-23, -0xd00000.0p-34, > + 0xcd0000.0p-23, 0x800000.0p-33, > + 0xce0000.0p-23, -0xe00000.0p-35, > + 0xcf0000.0p-23, 0xa60000.0p-33, > + 0xd00000.0p-23, -0x800000.0p-35, > + 0xd10000.0p-23, 0xb40000.0p-33, > + 0xd20000.0p-23, -0x800000.0p-35, > + 0xd30000.0p-23, 0xaa0000.0p-33, > + 0xd40000.0p-23, -0xe00000.0p-35, > + 0xd50000.0p-23, 0x880000.0p-33, > + 0xd60000.0p-23, -0xd00000.0p-34, > + 0xd70000.0p-23, 0x9c0000.0p-34, > + 0xd80000.0p-23, -0xb00000.0p-33, > + 0xd90000.0p-23, -0x800000.0p-38, > + 0xda0000.0p-23, 0xa40000.0p-33, > + 0xdb0000.0p-23, -0xdc0000.0p-34, > + 0xdc0000.0p-23, 0xc00000.0p-35, > + 0xdd0000.0p-23, 0xca0000.0p-33, > + 0xde0000.0p-23, -0xb80000.0p-34, > + 0xdf0000.0p-23, 0xd00000.0p-35, > + 0xe00000.0p-23, 0xc00000.0p-33, > + 0xe10000.0p-23, -0xf40000.0p-34, > + 0xe20000.0p-23, 0x800000.0p-37, > + 0xe30000.0p-23, 0x860000.0p-33, > + 0xe40000.0p-23, -0xc80000.0p-33, > + 0xe50000.0p-23, -0xa80000.0p-34, > + 0xe60000.0p-23, 0xe00000.0p-36, > + 0xe70000.0p-23, 0x880000.0p-33, > + 0xe80000.0p-23, -0xe00000.0p-33, > + 0xe90000.0p-23, -0xfc0000.0p-34, > + 0xea0000.0p-23, -0x800000.0p-35, > + 0xeb0000.0p-23, 0xe80000.0p-35, > + 0xec0000.0p-23, 0x900000.0p-33, > + 0xed0000.0p-23, 0xe20000.0p-33, > + 0xee0000.0p-23, -0xac0000.0p-33, > + 0xef0000.0p-23, -0xc80000.0p-34, > + 0xf00000.0p-23, -0x800000.0p-35, > + 0xf10000.0p-23, 0x800000.0p-35, > + 0xf20000.0p-23, 0xb80000.0p-34, > + 0xf30000.0p-23, 0x940000.0p-33, > + 0xf40000.0p-23, 0xc80000.0p-33, > + 0xf50000.0p-23, -0xf20000.0p-33, > + 0xf60000.0p-23, -0xc80000.0p-33, > + 0xf70000.0p-23, -0xa20000.0p-33, > + 0xf80000.0p-23, -0x800000.0p-33, > + 0xf90000.0p-23, -0xc40000.0p-34, > + 0xfa0000.0p-23, -0x900000.0p-34, > + 0xfb0000.0p-23, -0xc80000.0p-35, > + 0xfc0000.0p-23, -0x800000.0p-35, > + 0xfd0000.0p-23, -0x900000.0p-36, > + 0xfe0000.0p-23, -0x800000.0p-37, > + 0xff0000.0p-23, -0x800000.0p-39, > + 0x800000.0p-22, 0, > +}; > +#endif /* USE_UTAB */ > + > +#ifdef STRUCT_RETURN > +#define RETURN1(rp, v) do { \ > + (rp)->hi =3D (v); \ > + (rp)->lo_set =3D 0; \ > + return; \ > +} while (0) > + > +#define RETURN2(rp, h, l) do { \ > + (rp)->hi =3D (h); \ > + (rp)->lo =3D (l); \ > + (rp)->lo_set =3D 1; \ > + return; \ > +} while (0) > + > +struct ld { > + long double hi; > + long double lo; > + int lo_set; > +}; > +#else > +#define RETURN1(rp, v) RETURNF(v) > +#define RETURN2(rp, h, l) RETURNI((h) + (l)) > +#endif > + > +#ifdef STRUCT_RETURN > +static inline __always_inline void > +k_logl(long double x, struct ld *rp) > +#else > +long double > +logl(long double x) > +#endif > +{ > + long double d, val_hi, val_lo; > + double dd, dk; > + uint64_t lx, llx; > + int i, k; > + uint16_t hx; > + > + EXTRACT_LDBL128_WORDS(hx, lx, llx, x); > + k =3D -16383; > +#if 0 /* Hard to do efficiently. Don't do it until we support all modes= . */ > + if (x =3D=3D 1) > + RETURN1(rp, 0); /* log(1) =3D +0 in all rounding mo= des */ > +#endif > + if (hx =3D=3D 0 || hx >=3D 0x8000) { /* zero, negative or subnorma= l? */ > + if (((hx & 0x7fff) | lx | llx) =3D=3D 0) > + RETURN1(rp, -1 / zero); /* log(+-0) =3D -Inf */ > + if (hx !=3D 0) > + /* log(neg or NaN) =3D qNaN: */ > + RETURN1(rp, (x - x) / zero); > + x *=3D 0x1.0p113; /* subnormal; scale up x */ > + EXTRACT_LDBL128_WORDS(hx, lx, llx, x); > + k =3D -16383 - 113; > + } else if (hx >=3D 0x7fff) > + RETURN1(rp, x + x); /* log(Inf or NaN) =3D Inf or qNaN = */ > +#ifndef STRUCT_RETURN > + ENTERI(); > +#endif > + k +=3D hx; > + dk =3D k; > + > + /* Scale x to be in [1, 2). */ > + SET_LDBL_EXPSIGN(x, 0x3fff); > + > + /* 0 <=3D i <=3D INTERVALS: */ > +#define L2I (49 - LOG2_INTERVALS) > + i =3D (lx + (1LL << (L2I - 2))) >> (L2I - 1); > + > + /* > + * -0.005280 < d < 0.004838. In particular, the infinite- > + * precision |d| is <=3D 2**-7. Rounding of G(i) to 8 bits > + * ensures that d is representable without extra precision for > + * this bound on |d| (since when this calculation is expressed > + * as x*G(i)-1, the multiplication needs as many extra bits as > + * G(i) has and the subtraction cancels 8 bits). But for > + * most i (107 cases out of 129), the infinite-precision |d| > + * is <=3D 2**-8. G(i) is rounded to 9 bits for such i to give > + * better accuracy (this works by improving the bound on |d|, > + * which in turn allows rounding to 9 bits in more cases). > + * This is only important when the original x is near 1 -- it > + * lets us avoid using a special method to give the desired > + * accuracy for such x. > + */ > + if (0) > + d =3D x * G(i) - 1; > + else { > +#ifdef USE_UTAB > + d =3D (x - H(i)) * G(i) + E(i); > +#else > + long double x_hi; > + double x_lo; > + > + /* > + * Split x into x_hi + x_lo to calculate x*G(i)-1 exactly. > + * G(i) has at most 9 bits, so the splitting point is not > + * critical. > + */ > + INSERT_LDBL128_WORDS(x_hi, 0x3fff, lx, > + llx & 0xffffffffff000000ULL); > + x_lo =3D x - x_hi; > + d =3D x_hi * G(i) - 1 + x_lo * G(i); > +#endif > + } > + > + /* > + * Our algorithm depends on exact cancellation of F_lo(i) and > + * F_hi(i) with dk*ln_2_lo and dk*ln2_hi when k is -1 and i is > + * at the end of the table. This and other technical complications > + * make it difficult to avoid the double scaling in (dk*ln2) * > + * log(base) for base !=3D e without losing more accuracy and/or > + * efficiency than is gained. > + */ > + /* > + * Use double precision operations wherever possible, since > + * long double operations are emulated and were very slow on > + * the old sparc64 and unknown on the newer aarch64 and riscv > + * machines. Also, don't try to improve parallelism by > + * increasing the number of operations, since any parallelism > + * on such machines is needed for the emulation. Horner's > + * method is good for this, and is also good for accuracy. > + * Horner's method doesn't handle the `lo' term well, either > + * for efficiency or accuracy. However, for accuracy we > + * evaluate d * d * P2 separately to take advantage of by P2 > + * being exact, and this gives a good place to sum the 'lo' > + * term too. > + */ > + dd =3D (double)d; > + val_lo =3D d * d * d * (P3 + > + d * (P4 + d * (P5 + d * (P6 + d * (P7 + d * (P8 + > + dd * (P9 + dd * (P10 + dd * (P11 + dd * (P12 + dd * (P13 + > + dd * P14))))))))))) + (F_lo(i) + dk * ln2_lo) + d * d * P2; > + val_hi =3D d; > +#ifdef DEBUG > + if (fetestexcept(FE_UNDERFLOW)) > + breakpoint(); > +#endif > + > + _3sumF(val_hi, val_lo, F_hi(i) + dk * ln2_hi); > + RETURN2(rp, val_hi, val_lo); > +} > + > +long double > +log1pl(long double x) > +{ > + long double d, d_hi, f_lo, val_hi, val_lo; > + long double f_hi, twopminusk; > + double d_lo, dd, dk; > + uint64_t lx, llx; > + int i, k; > + int16_t ax, hx; > + > + DOPRINT_START(&x); > + EXTRACT_LDBL128_WORDS(hx, lx, llx, x); > + if (hx < 0x3fff) { /* x < 1, or x neg NaN */ > + ax =3D hx & 0x7fff; > + if (ax >=3D 0x3fff) { /* x <=3D -1, or x neg NaN */ > + if (ax =3D=3D 0x3fff && (lx | llx) =3D=3D 0) > + RETURNP(-1 / zero); /* log1p(-1) =3D -I= nf */ > + /* log1p(x < 1, or x NaN) =3D qNaN: */ > + RETURNP((x - x) / (x - x)); > + } > + if (ax <=3D 0x3f8d) { /* |x| < 2**-113 */ > + if ((int)x =3D=3D 0) > + RETURNP(x); /* x with inexact if x !=3D= 0 */ > + } > + f_hi =3D 1; > + f_lo =3D x; > + } else if (hx >=3D 0x7fff) { /* x +Inf or non-neg NaN */ > + RETURNP(x + x); /* log1p(Inf or NaN) =3D Inf or qNa= N */ > + } else if (hx < 0x40e1) { /* 1 <=3D x < 2**226 */ > + f_hi =3D x; > + f_lo =3D 1; > + } else { /* 2**226 <=3D x < +Inf */ > + f_hi =3D x; > + f_lo =3D 0; /* avoid underflow of the P3 term= */ > + } > + ENTERI(); > + x =3D f_hi + f_lo; > + f_lo =3D (f_hi - x) + f_lo; > + > + EXTRACT_LDBL128_WORDS(hx, lx, llx, x); > + k =3D -16383; > + > + k +=3D hx; > + dk =3D k; > + > + SET_LDBL_EXPSIGN(x, 0x3fff); > + twopminusk =3D 1; > + SET_LDBL_EXPSIGN(twopminusk, 0x7ffe - (hx & 0x7fff)); > + f_lo *=3D twopminusk; > + > + i =3D (lx + (1LL << (L2I - 2))) >> (L2I - 1); > + > + /* > + * x*G(i)-1 (with a reduced x) can be represented exactly, as > + * above, but now we need to evaluate the polynomial on d =3D > + * (x+f_lo)*G(i)-1 and extra precision is needed for that. > + * Since x+x_lo is a hi+lo decomposition and subtracting 1 > + * doesn't lose too many bits, an inexact calculation for > + * f_lo*G(i) is good enough. > + */ > + if (0) > + d_hi =3D x * G(i) - 1; > + else { > +#ifdef USE_UTAB > + d_hi =3D (x - H(i)) * G(i) + E(i); > +#else > + long double x_hi; > + double x_lo; > + > + INSERT_LDBL128_WORDS(x_hi, 0x3fff, lx, > + llx & 0xffffffffff000000ULL); > + x_lo =3D x - x_hi; > + d_hi =3D x_hi * G(i) - 1 + x_lo * G(i); > +#endif > + } > + d_lo =3D f_lo * G(i); > + > + /* > + * This is _2sumF(d_hi, d_lo) inlined. The condition > + * (d_hi =3D=3D 0 || |d_hi| >=3D |d_lo|) for using _2sumF() is not > + * always satisifed, so it is not clear that this works, but > + * it works in practice. It works even if it gives a wrong > + * normalized d_lo, since |d_lo| > |d_hi| implies that i is > + * nonzero and d is tiny, so the F(i) term dominates d_lo. > + * In float precision: > + * (By exhaustive testing, the worst case is d_hi =3D 0x1.bp-25. > + * And if d is only a little tinier than that, we would have > + * another underflow problem for the P3 term; this is also ruled > + * out by exhaustive testing.) > + */ > + d =3D d_hi + d_lo; > + d_lo =3D d_hi - d + d_lo; > + d_hi =3D d; > + > + dd =3D (double)d; > + val_lo =3D d * d * d * (P3 + > + d * (P4 + d * (P5 + d * (P6 + d * (P7 + d * (P8 + > + dd * (P9 + dd * (P10 + dd * (P11 + dd * (P12 + dd * (P13 + > + dd * P14))))))))))) + (F_lo(i) + dk * ln2_lo + d_lo) + d * d * = P2; > + val_hi =3D d_hi; > +#ifdef DEBUG > + if (fetestexcept(FE_UNDERFLOW)) > + breakpoint(); > +#endif > + > + _3sumF(val_hi, val_lo, F_hi(i) + dk * ln2_hi); > + RETURN2PI(val_hi, val_lo); > +} > + > +#ifdef STRUCT_RETURN > + > +long double > +logl(long double x) > +{ > + struct ld r; > + > + ENTERI(); > + DOPRINT_START(&x); > + k_logl(x, &r); > + RETURNSPI(&r); > +} > + > +/* > + * 29+113 bit decompositions. The bits are distributed so that the prod= ucts > + * of the hi terms are exact in double precision. The types are chosen = so > + * that the products of the hi terms are done in at least double precisi= on, > + * without any explicit conversions. More natural choices would require= a > + * slow long double precision multiplication. > + */ > +static const double > +invln10_hi =3D 4.3429448176175356e-1, /* 0x1bcb7b15000000.0p-5= 4 */ > +invln2_hi =3D 1.4426950402557850e0; /* 0x17154765000000.0p-5= 2 */ > +static const long double > +invln10_lo =3D 1.41498268538580090791605082294397000e-10L, /* 0x137= 287195355baaafad33dc323ee3.0p-145L */ > +invln2_lo =3D 6.33178418956604368501892137426645911e-10L, /* 0x15c= 17f0bbbe87fed0691d3e88eb57.0p-143L */ > +invln10_lo_plus_hi =3D invln10_lo + invln10_hi, > +invln2_lo_plus_hi =3D invln2_lo + invln2_hi; > + > +long double > +log10l(long double x) > +{ > + struct ld r; > + long double hi, lo; > + > + ENTERI(); > + DOPRINT_START(&x); > + k_logl(x, &r); > + if (!r.lo_set) > + RETURNPI(r.hi); > + _2sumF(r.hi, r.lo); > + hi =3D (float)r.hi; > + lo =3D r.lo + (r.hi - hi); > + RETURN2PI(invln10_hi * hi, > + invln10_lo_plus_hi * lo + invln10_lo * hi); > +} > + > +long double > +log2l(long double x) > +{ > + struct ld r; > + long double hi, lo; > + > + ENTERI(); > + DOPRINT_START(&x); > + k_logl(x, &r); > + if (!r.lo_set) > + RETURNPI(r.hi); > + _2sumF(r.hi, r.lo); > + hi =3D (float)r.hi; > + lo =3D r.lo + (r.hi - hi); > + RETURN2PI(invln2_hi * hi, > + invln2_lo_plus_hi * lo + invln2_lo * hi); > +} > + > +#endif /* STRUCT_RETURN */ > diff --git a/newlib/libm/ld80/b_expl.c b/newlib/libm/ld80/b_expl.c > new file mode 100644 > index 000000000..21bacf449 > --- /dev/null > +++ b/newlib/libm/ld80/b_expl.c > @@ -0,0 +1,113 @@ > +/*- > + * SPDX-License-Identifier: BSD-3-Clause > + * > + * Copyright (c) 1985, 1993 > + * The Regents of the University of California. All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * 3. Neither the name of the University nor the names of its contributo= rs > + * may be used to endorse or promote products derived from this softw= are > + * without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' A= ND > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIA= BLE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +/* > + * See bsdsrc/b_exp.c for implementation details. > + * > + * bsdrc/b_exp.c converted to long double by Steven G. Kargl. > + */ > + > +#include "fpmath.h" > +#include "math_private.h" > + > +static const union IEEEl2bits > + p0u =3D LD80C(0xaaaaaaaaaaaaaaab, -3, 1.66666666666666666671e-01= L), > + p1u =3D LD80C(0xb60b60b60b60b59a, -9, -2.77777777777777775377e-03= L), > + p2u =3D LD80C(0x8ab355e008a3cfce, -14, 6.61375661375629297465e-05= L), > + p3u =3D LD80C(0xddebbc994b0c1376, -20, -1.65343915327882529784e-06= L), > + p4u =3D LD80C(0xb354784cb4ef4c41, -25, 4.17535101591534118469e-08= L), > + p5u =3D LD80C(0x913e8a718382ce75, -30, -1.05679137034774806475e-09= L), > + p6u =3D LD80C(0xe8f0042aa134502e, -36, 2.64819349895429516863e-11= L); > +#define p1 (p0u.e) > +#define p2 (p1u.e) > +#define p3 (p2u.e) > +#define p4 (p3u.e) > +#define p5 (p4u.e) > +#define p6 (p5u.e) > +#define p7 (p6u.e) > + > +/* > + * lnhuge =3D (LDBL_MAX_EXP + 9) * log(2.) > + * lntiny =3D (LDBL_MIN_EXP - 64 - 10) * log(2.) > + * invln2 =3D 1 / log(2.) > + */ > +static const union IEEEl2bits > +ln2hiu =3D LD80C(0xb17217f700000000, -1, 6.93147180369123816490e-01L)= , > +ln2lou =3D LD80C(0xd1cf79abc9e3b398, -33, 1.90821492927058781614e-10L)= , > +lnhugeu =3D LD80C(0xb18b0c0330a8fad9, 13, 1.13627617309191834574e+04L)= , > +lntinyu =3D LD80C(0xb236f28a68bc3bd7, 13, -1.14057368561139000667e+04L)= , > +invln2u =3D LD80C(0xb8aa3b295c17f0bc, 0, 1.44269504088896340739e+00L)= ; > +#define ln2hi (ln2hiu.e) > +#define ln2lo (ln2lou.e) > +#define lnhuge (lnhugeu.e) > +#define lntiny (lntinyu.e) > +#define invln2 (invln2u.e) > + > +/* returns exp(r =3D x + c) for |c| < |x| with no overlap. */ > + > +static long double > +__exp__D(long double x, long double c) > +{ > + long double hi, lo, z; > + int k; > + > + if (x !=3D x) /* x is NaN. */ > + return(x); > + > + if (x <=3D lnhuge) { > + if (x >=3D lntiny) { > + /* argument reduction: x --> x - k*ln2 */ > + z =3D invln2 * x; > + k =3D z + copysignl(0.5L, x); > + > + /* > + * Express (x + c) - k * ln2 as hi - lo. > + * Let x =3D hi - lo rounded. > + */ > + hi =3D x - k * ln2hi; /* Exact. */ > + lo =3D k * ln2lo - c; > + x =3D hi - lo; > + > + /* Return 2^k*[1+x+x*c/(2+c)] */ > + z =3D x * x; > + c =3D x - z * (p1 + z * (p2 + z * (p3 + z * (p4 + > + z * (p5 + z * (p6 + z * p7)))))); > + c =3D (x * c) / (2 - c); > + > + return (ldexpl(1 + (hi - (lo - c)), k)); > + } else { > + /* exp(-INF) is 0. exp(-big) underflows to 0. */ > + return (isfinite(x) ? ldexpl(1., -5000) : 0); > + } > + } else > + /* exp(INF) is INF, exp(+big#) overflows to INF */ > + return (isfinite(x) ? ldexpl(1., 5000) : x); > +} > diff --git a/newlib/libm/ld80/b_logl.c b/newlib/libm/ld80/b_logl.c > new file mode 100644 > index 000000000..b11eacbe1 > --- /dev/null > +++ b/newlib/libm/ld80/b_logl.c > @@ -0,0 +1,375 @@ > +/*- > + * SPDX-License-Identifier: BSD-3-Clause > + * > + * Copyright (c) 1992, 1993 > + * The Regents of the University of California. All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * 3. Neither the name of the University nor the names of its contributo= rs > + * may be used to endorse or promote products derived from this softw= are > + * without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' A= ND > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIA= BLE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +/* > + * See bsdsrc/b_log.c for implementation details. > + * > + * bsdrc/b_log.c converted to long double by Steven G. Kargl. > + */ > + > +#define N 128 > + > +/* > + * Coefficients in the polynomial approximation of log(1+f/F). > + * Domain of x is [0,1./256] with 2**(-84.48) precision. > + */ > +static const union IEEEl2bits > + a1u =3D LD80C(0xaaaaaaaaaaaaaaab, -4, 8.33333333333333333356e-02= L), > + a2u =3D LD80C(0xcccccccccccccd29, -7, 1.25000000000000000781e-02= L), > + a3u =3D LD80C(0x9249249241ed3764, -9, 2.23214285711721994134e-03= L), > + a4u =3D LD80C(0xe38e959e1e7e01cf, -12, 4.34030476540000360640e-04= L); > +#define A1 (a1u.e) > +#define A2 (a2u.e) > +#define A3 (a3u.e) > +#define A4 (a4u.e) > + > +/* > + * Table of log(Fj) =3D logF_head[j] + logF_tail[j], for Fj =3D 1+j/128. > + * Used for generation of extend precision logarithms. > + * The constant 35184372088832 is 2^45, so the divide is exact. > + * It ensures correct reading of logF_head, even for inaccurate > + * decimal-to-binary conversion routines. (Everybody gets the > + * right answer for integers less than 2^53.) > + * Values for log(F) were generated using error < 10^-57 absolute > + * with the bc -l package. > + */ > + > +static double logF_head[N+1] =3D { > + 0., > + .007782140442060381246, > + .015504186535963526694, > + .023167059281547608406, > + .030771658666765233647, > + .038318864302141264488, > + .045809536031242714670, > + .053244514518837604555, > + .060624621816486978786, > + .067950661908525944454, > + .075223421237524235039, > + .082443669210988446138, > + .089612158689760690322, > + .096729626458454731618, > + .103796793681567578460, > + .110814366340264314203, > + .117783035656430001836, > + .124703478501032805070, > + .131576357788617315236, > + .138402322859292326029, > + .145182009844575077295, > + .151916042025732167530, > + .158605030176659056451, > + .165249572895390883786, > + .171850256926518341060, > + .178407657472689606947, > + .184922338493834104156, > + .191394852999565046047, > + .197825743329758552135, > + .204215541428766300668, > + .210564769107350002741, > + .216873938300523150246, > + .223143551314024080056, > + .229374101064877322642, > + .235566071312860003672, > + .241719936886966024758, > + .247836163904594286577, > + .253915209980732470285, > + .259957524436686071567, > + .265963548496984003577, > + .271933715484010463114, > + .277868451003087102435, > + .283768173130738432519, > + .289633292582948342896, > + .295464212893421063199, > + .301261330578199704177, > + .307025035294827830512, > + .312755710004239517729, > + .318453731118097493890, > + .324119468654316733591, > + .329753286372579168528, > + .335355541920762334484, > + .340926586970454081892, > + .346466767346100823488, > + .351976423156884266063, > + .357455888922231679316, > + .362905493689140712376, > + .368325561158599157352, > + .373716409793814818840, > + .379078352934811846353, > + .384411698910298582632, > + .389716751140440464951, > + .394993808240542421117, > + .400243164127459749579, > + .405465108107819105498, > + .410659924985338875558, > + .415827895143593195825, > + .420969294644237379543, > + .426084395310681429691, > + .431173464818130014464, > + .436236766774527495726, > + .441274560805140936281, > + .446287102628048160113, > + .451274644139630254358, > + .456237433481874177232, > + .461175715122408291790, > + .466089729924533457960, > + .470979715219073113985, > + .475845904869856894947, > + .480688529345570714212, > + .485507815781602403149, > + .490303988045525329653, > + .495077266798034543171, > + .499827869556611403822, > + .504556010751912253908, > + .509261901790523552335, > + .513945751101346104405, > + .518607764208354637958, > + .523248143765158602036, > + .527867089620485785417, > + .532464798869114019908, > + .537041465897345915436, > + .541597282432121573947, > + .546132437597407260909, > + .550647117952394182793, > + .555141507540611200965, > + .559615787935399566777, > + .564070138285387656651, > + .568504735352689749561, > + .572919753562018740922, > + .577315365035246941260, > + .581691739635061821900, > + .586049045003164792433, > + .590387446602107957005, > + .594707107746216934174, > + .599008189645246602594, > + .603290851438941899687, > + .607555250224322662688, > + .611801541106615331955, > + .616029877215623855590, > + .620240409751204424537, > + .624433288012369303032, > + .628608659422752680256, > + .632766669570628437213, > + .636907462236194987781, > + .641031179420679109171, > + .645137961373620782978, > + .649227946625615004450, > + .653301272011958644725, > + .657358072709030238911, > + .661398482245203922502, > + .665422632544505177065, > + .669430653942981734871, > + .673422675212350441142, > + .677398823590920073911, > + .681359224807238206267, > + .685304003098281100392, > + .689233281238557538017, > + .693147180560117703862 > +}; > + > +static double logF_tail[N+1] =3D { > + 0., > + -.00000000000000543229938420049, > + .00000000000000172745674997061, > + -.00000000000001323017818229233, > + -.00000000000001154527628289872, > + -.00000000000000466529469958300, > + .00000000000005148849572685810, > + -.00000000000002532168943117445, > + -.00000000000005213620639136504, > + -.00000000000001819506003016881, > + .00000000000006329065958724544, > + .00000000000008614512936087814, > + -.00000000000007355770219435028, > + .00000000000009638067658552277, > + .00000000000007598636597194141, > + .00000000000002579999128306990, > + -.00000000000004654729747598444, > + -.00000000000007556920687451336, > + .00000000000010195735223708472, > + -.00000000000017319034406422306, > + -.00000000000007718001336828098, > + .00000000000010980754099855238, > + -.00000000000002047235780046195, > + -.00000000000008372091099235912, > + .00000000000014088127937111135, > + .00000000000012869017157588257, > + .00000000000017788850778198106, > + .00000000000006440856150696891, > + .00000000000016132822667240822, > + -.00000000000007540916511956188, > + -.00000000000000036507188831790, > + .00000000000009120937249914984, > + .00000000000018567570959796010, > + -.00000000000003149265065191483, > + -.00000000000009309459495196889, > + .00000000000017914338601329117, > + -.00000000000001302979717330866, > + .00000000000023097385217586939, > + .00000000000023999540484211737, > + .00000000000015393776174455408, > + -.00000000000036870428315837678, > + .00000000000036920375082080089, > + -.00000000000009383417223663699, > + .00000000000009433398189512690, > + .00000000000041481318704258568, > + -.00000000000003792316480209314, > + .00000000000008403156304792424, > + -.00000000000034262934348285429, > + .00000000000043712191957429145, > + -.00000000000010475750058776541, > + -.00000000000011118671389559323, > + .00000000000037549577257259853, > + .00000000000013912841212197565, > + .00000000000010775743037572640, > + .00000000000029391859187648000, > + -.00000000000042790509060060774, > + .00000000000022774076114039555, > + .00000000000010849569622967912, > + -.00000000000023073801945705758, > + .00000000000015761203773969435, > + .00000000000003345710269544082, > + -.00000000000041525158063436123, > + .00000000000032655698896907146, > + -.00000000000044704265010452446, > + .00000000000034527647952039772, > + -.00000000000007048962392109746, > + .00000000000011776978751369214, > + -.00000000000010774341461609578, > + .00000000000021863343293215910, > + .00000000000024132639491333131, > + .00000000000039057462209830700, > + -.00000000000026570679203560751, > + .00000000000037135141919592021, > + -.00000000000017166921336082431, > + -.00000000000028658285157914353, > + -.00000000000023812542263446809, > + .00000000000006576659768580062, > + -.00000000000028210143846181267, > + .00000000000010701931762114254, > + .00000000000018119346366441110, > + .00000000000009840465278232627, > + -.00000000000033149150282752542, > + -.00000000000018302857356041668, > + -.00000000000016207400156744949, > + .00000000000048303314949553201, > + -.00000000000071560553172382115, > + .00000000000088821239518571855, > + -.00000000000030900580513238244, > + -.00000000000061076551972851496, > + .00000000000035659969663347830, > + .00000000000035782396591276383, > + -.00000000000046226087001544578, > + .00000000000062279762917225156, > + .00000000000072838947272065741, > + .00000000000026809646615211673, > + -.00000000000010960825046059278, > + .00000000000002311949383800537, > + -.00000000000058469058005299247, > + -.00000000000002103748251144494, > + -.00000000000023323182945587408, > + -.00000000000042333694288141916, > + -.00000000000043933937969737844, > + .00000000000041341647073835565, > + .00000000000006841763641591466, > + .00000000000047585534004430641, > + .00000000000083679678674757695, > + -.00000000000085763734646658640, > + .00000000000021913281229340092, > + -.00000000000062242842536431148, > + -.00000000000010983594325438430, > + .00000000000065310431377633651, > + -.00000000000047580199021710769, > + -.00000000000037854251265457040, > + .00000000000040939233218678664, > + .00000000000087424383914858291, > + .00000000000025218188456842882, > + -.00000000000003608131360422557, > + -.00000000000050518555924280902, > + .00000000000078699403323355317, > + -.00000000000067020876961949060, > + .00000000000016108575753932458, > + .00000000000058527188436251509, > + -.00000000000035246757297904791, > + -.00000000000018372084495629058, > + .00000000000088606689813494916, > + .00000000000066486268071468700, > + .00000000000063831615170646519, > + .00000000000025144230728376072, > + -.00000000000017239444525614834 > +}; > +/* > + * Extra precision variant, returning struct {double a, b;}; > + * log(x) =3D a + b to 63 bits, with 'a' rounded to 24 bits. > + */ > +static struct Double > +__log__D(long double x) > +{ > + int m, j; > + long double F, f, g, q, u, v, u1, u2; > + struct Double r; > + > + /* > + * Argument reduction: 1 <=3D g < 2; x/2^m =3D g; > + * y =3D F*(1 + f/F) for |f| <=3D 2^-8 > + */ > + g =3D frexpl(x, &m); > + g *=3D 2; > + m--; > + if (m =3D=3D DBL_MIN_EXP - 1) { > + j =3D ilogbl(g); > + m +=3D j; > + g =3D ldexpl(g, -j); > + } > + j =3D N * (g - 1) + 0.5L; > + F =3D (1.L / N) * j + 1; > + f =3D g - F; > + > + g =3D 1 / (2 * F + f); > + u =3D 2 * f * g; > + v =3D u * u; > + q =3D u * v * (A1 + v * (A2 + v * (A3 + v * A4))); > + if (m | j) { > + u1 =3D u + 513; > + u1 -=3D 513; > + } else { > + u1 =3D (float)u; > + } > + u2 =3D (2 * (f - F * u1) - u1 * f) * g; > + > + u1 +=3D m * (long double)logF_head[N] + logF_head[j]; > + > + u2 +=3D logF_tail[j]; > + u2 +=3D q; > + u2 +=3D logF_tail[N] * m; > + r.a =3D (float)(u1 + u2); /* Only difference is here. */ > + r.b =3D (u1 - r.a) + u2; > + return (r); > +} > diff --git a/newlib/libm/ld80/b_tgammal.c b/newlib/libm/ld80/b_tgammal.c > new file mode 100644 > index 000000000..121248adb > --- /dev/null > +++ b/newlib/libm/ld80/b_tgammal.c > @@ -0,0 +1,419 @@ > +/*- > + * SPDX-License-Identifier: BSD-3-Clause > + * > + * Copyright (c) 1992, 1993 > + * The Regents of the University of California. All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * 3. Neither the name of the University nor the names of its contributo= rs > + * may be used to endorse or promote products derived from this softw= are > + * without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' A= ND > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIA= BLE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +/* > + * The original code, FreeBSD's old svn r93211, contain the following > + * attribution: > + * > + * This code by P. McIlroy, Oct 1992; > + * > + * The financial support of UUNET Communications Services is greatful= ly > + * acknowledged. > + * > + * bsdrc/b_tgamma.c converted to long double by Steven G. Kargl. > + */ > + > +/* > + * See bsdsrc/t_tgamma.c for implementation details. > + */ > + > +#include > + > +#if LDBL_MAX_EXP !=3D 0x4000 > +#error "Unsupported long double format" > +#endif > + > +#ifdef __i386__ > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +/* Used in b_log.c and below. */ > +struct Double { > + long double a; > + long double b; > +}; > + > +#include "b_logl.c" > +#include "b_expl.c" > + > +static const double zero =3D 0.; > +static const volatile double tiny =3D 1e-300; > +/* > + * x >=3D 6 > + * > + * Use the asymptotic approximation (Stirling's formula) adjusted for > + * equal-ripples: > + * > + * log(G(x)) ~=3D (x-0.5)*(log(x)-1) + 0.5(log(2*pi)-1) + 1/x*P(1/(x*x)) > + * > + * Keep extra precision in multiplying (x-.5)(log(x)-1), to avoid > + * premature round-off. > + * > + * Accurate to max(ulp(1/128) absolute, 2^-66 relative) error. > + */ > + > +/* > + * The following is a decomposition of 0.5 * (log(2*pi) - 1) into the > + * first 12 bits in ln2pi_hi and the trailing 64 bits in ln2pi_lo. The > + * variables are clearly misnamed. > + */ > +static const union IEEEl2bits > +ln2pi_hiu =3D LD80C(0xd680000000000000, -2, 4.18945312500000000000e-01= L), > +ln2pi_lou =3D LD80C(0xe379b414b596d687, -18, -6.77929532725821967032e-06= L); > +#define ln2pi_hi (ln2pi_hiu.e) > +#define ln2pi_lo (ln2pi_lou.e) > + > +static const union IEEEl2bits > + Pa0u =3D LD80C(0xaaaaaaaaaaaaaaaa, -4, 8.33333333333333333288e-02L= ), > + Pa1u =3D LD80C(0xb60b60b60b5fcd59, -9, -2.77777777777776516326e-03L= ), > + Pa2u =3D LD80C(0xd00d00cffbb47014, -11, 7.93650793635429639018e-04L= ), > + Pa3u =3D LD80C(0x9c09c07c0805343e, -11, -5.95238087960599252215e-04L= ), > + Pa4u =3D LD80C(0xdca8d31f8e6e5e8f, -11, 8.41749082509607342883e-04L= ), > + Pa5u =3D LD80C(0xfb4d4289632f1638, -10, -1.91728055205541624556e-03L= ), > + Pa6u =3D LD80C(0xd15a4ba04078d3f8, -8, 6.38893788027752396194e-03L= ), > + Pa7u =3D LD80C(0xe877283110bcad95, -6, -2.83771309846297590312e-02L= ), > + Pa8u =3D LD80C(0x8da97eed13717af8, -3, 1.38341887683837576925e-01L= ), > + Pa9u =3D LD80C(0xf093b1c1584e30ce, -2, -4.69876818515470146031e-01L= ); > +#define Pa0 (Pa0u.e) > +#define Pa1 (Pa1u.e) > +#define Pa2 (Pa2u.e) > +#define Pa3 (Pa3u.e) > +#define Pa4 (Pa4u.e) > +#define Pa5 (Pa5u.e) > +#define Pa6 (Pa6u.e) > +#define Pa7 (Pa7u.e) > +#define Pa8 (Pa8u.e) > +#define Pa9 (Pa9u.e) > + > +static struct Double > +large_gam(long double x) > +{ > + long double p, z, thi, tlo, xhi, xlo; > + long double logx; > + struct Double u; > + > + z =3D 1 / (x * x); > + p =3D Pa0 + z * (Pa1 + z * (Pa2 + z * (Pa3 + z * (Pa4 + z * (Pa5 + > + z * (Pa6 + z * (Pa7 + z * (Pa8 + z * Pa9)))))))); > + p =3D p / x; > + > + u =3D __log__D(x); > + u.a -=3D 1; > + > + /* Split (x - 0.5) in high and low parts. */ > + x -=3D 0.5L; > + xhi =3D (float)x; > + xlo =3D x - xhi; > + > + /* Compute t =3D (x-.5)*(log(x)-1) in extra precision. */ > + thi =3D xhi * u.a; > + tlo =3D xlo * u.a + x * u.b; > + > + /* Compute thi + tlo + ln2pi_hi + ln2pi_lo + p. */ > + tlo +=3D ln2pi_lo; > + tlo +=3D p; > + u.a =3D ln2pi_hi + tlo; > + u.a +=3D thi; > + u.b =3D thi - u.a; > + u.b +=3D ln2pi_hi; > + u.b +=3D tlo; > + return (u); > +} > +/* > + * Rational approximation, A0 + x * x * P(x) / Q(x), on the interval > + * [1.066.., 2.066..] accurate to 4.25e-19. > + * > + * Returns r.a + r.b =3D a0 + (z + c)^2 * p / q, with r.a truncated. > + */ > +static const union IEEEl2bits > + a0_hiu =3D LD80C(0xe2b6e4153a57746c, -1, 8.85603194410888700265e-01= L), > + a0_lou =3D LD80C(0x851566d40f32c76d, -66, 1.40907742727049706207e-20= L); > +#define a0_hi (a0_hiu.e) > +#define a0_lo (a0_lou.e) > + > +static const union IEEEl2bits > +P0u =3D LD80C(0xdb629fb9bbdc1c1d, -2, 4.28486815855585429733e-01L), > +P1u =3D LD80C(0xe6f4f9f5641aa6be, -3, 2.25543885805587730552e-01L), > +P2u =3D LD80C(0xead1bd99fdaf7cc1, -6, 2.86644652514293482381e-02L), > +P3u =3D LD80C(0x9ccc8b25838ab1e0, -8, 4.78512567772456362048e-03L), > +P4u =3D LD80C(0x8f0c4383ef9ce72a, -9, 2.18273781132301146458e-03L), > +P5u =3D LD80C(0xe732ab2c0a2778da, -13, 2.20487522485636008928e-04L), > +P6u =3D LD80C(0xce70b27ca822b297, -16, 2.46095923774929264284e-05L), > +P7u =3D LD80C(0xa309e2e16fb63663, -19, 2.42946473022376182921e-06L), > +P8u =3D LD80C(0xaf9c110efb2c633d, -23, 1.63549217667765869987e-07L), > +Q1u =3D LD80C(0xd4d7422719f48f15, -1, 8.31409582658993993626e-01L), > +Q2u =3D LD80C(0xe13138ea404f1268, -5, -5.49785826915643198508e-02L), > +Q3u =3D LD80C(0xd1c6cc91989352c0, -4, -1.02429960435139887683e-01L), > +Q4u =3D LD80C(0xa7e9435a84445579, -7, 1.02484853505908820524e-02L), > +Q5u =3D LD80C(0x83c7c34db89b7bda, -8, 4.02161632832052872697e-03L), > +Q6u =3D LD80C(0xbed06bf6e1c14e5b, -11, -7.27898206351223022157e-04L), > +Q7u =3D LD80C(0xef05bf841d4504c0, -18, 7.12342421869453515194e-06L), > +Q8u =3D LD80C(0xf348d08a1ff53cb1, -19, 3.62522053809474067060e-06L); > +#define P0 (P0u.e) > +#define P1 (P1u.e) > +#define P2 (P2u.e) > +#define P3 (P3u.e) > +#define P4 (P4u.e) > +#define P5 (P5u.e) > +#define P6 (P6u.e) > +#define P7 (P7u.e) > +#define P8 (P8u.e) > +#define Q1 (Q1u.e) > +#define Q2 (Q2u.e) > +#define Q3 (Q3u.e) > +#define Q4 (Q4u.e) > +#define Q5 (Q5u.e) > +#define Q6 (Q6u.e) > +#define Q7 (Q7u.e) > +#define Q8 (Q8u.e) > + > +static struct Double > +ratfun_gam(long double z, long double c) > +{ > + long double p, q, thi, tlo; > + struct Double r; > + > + q =3D 1 + z * (Q1 + z * (Q2 + z * (Q3 + z * (Q4 + z * (Q5 + > + z * (Q6 + z * (Q7 + z * Q8))))))); > + p =3D P0 + z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * (P5 + > + z * (P6 + z * (P7 + z * P8))))))); > + p =3D p / q; > + > + /* Split z into high and low parts. */ > + thi =3D (float)z; > + tlo =3D (z - thi) + c; > + tlo *=3D (thi + z); > + > + /* Split (z+c)^2 into high and low parts. */ > + thi *=3D thi; > + q =3D thi; > + thi =3D (float)thi; > + tlo +=3D (q - thi); > + > + /* Split p/q into high and low parts. */ > + r.a =3D (float)p; > + r.b =3D p - r.a; > + > + tlo =3D tlo * p + thi * r.b + a0_lo; > + thi *=3D r.a; /* t =3D (z+c)^2*(P/Q) */ > + r.a =3D (float)(thi + a0_hi); > + r.b =3D ((a0_hi - r.a) + thi) + tlo; > + return (r); /* r =3D a0 + t */ > +} > +/* > + * x < 6 > + * > + * Use argument reduction G(x+1) =3D xG(x) to reach the range [1.066124, > + * 2.066124]. Use a rational approximation centered at the minimum > + * (x0+1) to ensure monotonicity. > + * > + * Good to < 1 ulp. (provably .90 ulp; .87 ulp on 1,000,000 runs.) > + * It also has correct monotonicity. > + */ > +static const union IEEEl2bits > + xm1u =3D LD80C(0xec5b0c6ad7c7edc3, -2, 4.61632144968362341254e-01L); > +#define x0 (xm1u.e) > + > +static const double > + left =3D -0.3955078125; /* left boundary for rat. approx */ > + > +static long double > +small_gam(long double x) > +{ > + long double t, y, ym1; > + struct Double yy, r; > + > + y =3D x - 1; > + > + if (y <=3D 1 + (left + x0)) { > + yy =3D ratfun_gam(y - x0, 0); > + return (yy.a + yy.b); > + } > + > + r.a =3D (float)y; > + yy.a =3D r.a - 1; > + y =3D y - 1 ; > + r.b =3D yy.b =3D y - yy.a; > + > + /* Argument reduction: G(x+1) =3D x*G(x) */ > + for (ym1 =3D y - 1; ym1 > left + x0; y =3D ym1--, yy.a--) { > + t =3D r.a * yy.a; > + r.b =3D r.a * yy.b + y * r.b; > + r.a =3D (float)t; > + r.b +=3D (t - r.a); > + } > + > + /* Return r*tgamma(y). */ > + yy =3D ratfun_gam(y - x0, 0); > + y =3D r.b * (yy.a + yy.b) + r.a * yy.b; > + y +=3D yy.a * r.a; > + return (y); > +} > +/* > + * Good on (0, 1+x0+left]. Accurate to 1 ulp. > + */ > +static long double > +smaller_gam(long double x) > +{ > + long double d, rhi, rlo, t, xhi, xlo; > + struct Double r; > + > + if (x < x0 + left) { > + t =3D (float)x; > + d =3D (t + x) * (x - t); > + t *=3D t; > + xhi =3D (float)(t + x); > + xlo =3D x - xhi; > + xlo +=3D t; > + xlo +=3D d; > + t =3D 1 - x0; > + t +=3D x; > + d =3D 1 - x0; > + d -=3D t; > + d +=3D x; > + x =3D xhi + xlo; > + } else { > + xhi =3D (float)x; > + xlo =3D x - xhi; > + t =3D x - x0; > + d =3D - x0 - t; > + d +=3D x; > + } > + > + r =3D ratfun_gam(t, d); > + d =3D (float)(r.a / x); > + r.a -=3D d * xhi; > + r.a -=3D d * xlo; > + r.a +=3D r.b; > + > + return (d + r.a / x); > +} > +/* > + * x < 0 > + * > + * Use reflection formula, G(x) =3D pi/(sin(pi*x)*x*G(x)). > + * At negative integers, return NaN and raise invalid. > + */ > +static const union IEEEl2bits > +piu =3D LD80C(0xc90fdaa22168c235, 1, 3.14159265358979323851e+00L); > +#define pi (piu.e) > + > +static long double > +neg_gam(long double x) > +{ > + int sgn =3D 1; > + struct Double lg, lsine; > + long double y, z; > + > + y =3D ceill(x); > + if (y =3D=3D x) /* Negative integer. */ > + return ((x - x) / zero); > + > + z =3D y - x; > + if (z > 0.5) > + z =3D 1 - z; > + > + y =3D y / 2; > + if (y =3D=3D ceill(y)) > + sgn =3D -1; > + > + if (z < 0.25) > + z =3D sinpil(z); > + else > + z =3D cospil(0.5 - z); > + > + /* Special case: G(1-x) =3D Inf; G(x) may be nonzero. */ > + if (x < -1753) { > + > + if (x < -1760) > + return (sgn * tiny * tiny); > + y =3D expl(lgammal(x) / 2); > + y *=3D y; > + return (sgn < 0 ? -y : y); > + } > + > + > + y =3D 1 - x; > + if (1 - y =3D=3D x) > + y =3D tgammal(y); > + else /* 1-x is inexact */ > + y =3D - x * tgammal(-x); > + > + if (sgn < 0) y =3D -y; > + return (pi / (y * z)); > +} > +/* > + * xmax comes from lgamma(xmax) - emax * log(2) =3D 0. > + * static const float xmax =3D 35.040095f > + * static const double xmax =3D 171.624376956302725; > + * ld80: LD80C(0xdb718c066b352e20, 10, 1.75554834290446291689e+03L), > + * ld128: 1.75554834290446291700388921607020320e+03L, > + * > + * iota is a sloppy threshold to isolate x =3D 0. > + */ > +static const double xmax =3D 1755.54834290446291689; > +static const double iota =3D 0x1p-116; > + > +long double > +tgammal(long double x) > +{ > + struct Double u; > + > + ENTERI(); > + > + if (x >=3D 6) { > + if (x > xmax) > + RETURNI(x / zero); > + u =3D large_gam(x); > + RETURNI(__exp__D(u.a, u.b)); > + } > + > + if (x >=3D 1 + left + x0) > + RETURNI(small_gam(x)); > + > + if (x > iota) > + RETURNI(smaller_gam(x)); > + > + if (x > -iota) { > + if (x !=3D 0) > + u.a =3D 1 - tiny; /* raise inexact */ > + RETURNI(1 / x); > + } > + > + if (!isfinite(x)) > + RETURNI(x - x); /* x is NaN or -Inf */ > + > + RETURNI(neg_gam(x)); > +} > diff --git a/newlib/libm/ld80/e_lgammal_r.c b/newlib/libm/ld80/e_lgammal_= r.c > new file mode 100644 > index 000000000..f56758b18 > --- /dev/null > +++ b/newlib/libm/ld80/e_lgammal_r.c > @@ -0,0 +1,358 @@ > +/* @(#)e_lgamma_r.c 1.3 95/01/18 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See e_lgamma_r.c for complete comments. > + * > + * Converted to long double by Steven G. Kargl. > + */ > + > +#ifdef __i386__ > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +static const volatile double vzero =3D 0; > + > +static const double > +zero=3D 0, > +half=3D 0.5, > +one =3D 1; > + > +static const union IEEEl2bits > +piu =3D LD80C(0xc90fdaa22168c235, 1, 3.14159265358979323851e+00L); > +#define pi (piu.e) > +/* > + * Domain y in [0x1p-70, 0.27], range ~[-4.5264e-22, 4.5264e-22]: > + * |(lgamma(2 - y) + y / 2) / y - a(y)| < 2**-70.9 > + */ > +static const union IEEEl2bits > +a0u =3D LD80C(0x9e233f1bed863d26, -4, 7.72156649015328606028e-02L), > +a1u =3D LD80C(0xa51a6625307d3249, -2, 3.22467033424113218889e-01L), > +a2u =3D LD80C(0x89f000d2abafda8c, -4, 6.73523010531979398946e-02L), > +a3u =3D LD80C(0xa8991563eca75f26, -6, 2.05808084277991211934e-02L), > +a4u =3D LD80C(0xf2027e10634ce6b6, -8, 7.38555102796070454026e-03L), > +a5u =3D LD80C(0xbd6eb76dd22187f4, -9, 2.89051035162703932972e-03L), > +a6u =3D LD80C(0x9c562ab05e0458ed, -10, 1.19275351624639999297e-03L), > +a7u =3D LD80C(0x859baed93ee48e46, -11, 5.09674593842117925320e-04L), > +a8u =3D LD80C(0xe9f28a4432949af2, -13, 2.23109648015769155122e-04L), > +a9u =3D LD80C(0xd12ad0d9b93c6bb0, -14, 9.97387167479808509830e-05L), > +a10u=3D LD80C(0xb7522643c78a219b, -15, 4.37071076331030136818e-05L), > +a11u=3D LD80C(0xca024dcdece2cb79, -16, 2.40813493372040143061e-05L), > +a12u=3D LD80C(0xbb90fb6968ebdbf9, -19, 2.79495621083634031729e-06L), > +a13u=3D LD80C(0xba1c9ffeeae07b37, -17, 1.10931287015513924136e-05L); > +#define a0 (a0u.e) > +#define a1 (a1u.e) > +#define a2 (a2u.e) > +#define a3 (a3u.e) > +#define a4 (a4u.e) > +#define a5 (a5u.e) > +#define a6 (a6u.e) > +#define a7 (a7u.e) > +#define a8 (a8u.e) > +#define a9 (a9u.e) > +#define a10 (a10u.e) > +#define a11 (a11u.e) > +#define a12 (a12u.e) > +#define a13 (a13u.e) > +/* > + * Domain x in [tc-0.24, tc+0.28], range ~[-6.1205e-22, 6.1205e-22]: > + * |(lgamma(x) - tf) - t(x - tc)| < 2**-70.5 > + */ > +static const union IEEEl2bits > +tcu =3D LD80C(0xbb16c31ab5f1fb71, 0, 1.46163214496836234128e+00L), > +tfu =3D LD80C(0xf8cdcde61c520e0f, -4, -1.21486290535849608093e-01L), > +ttu =3D LD80C(0xd46ee54b27d4de99, -69, -2.81152980996018785880e-21L), > +t0u =3D LD80C(0x80b9406556a62a6b, -68, 3.40728634996055147231e-21L), > +t1u =3D LD80C(0xc7e9c6f6df3f8c39, -67, -1.05833162742737073665e-20L), > +t2u =3D LD80C(0xf7b95e4771c55d51, -2, 4.83836122723810583532e-01L), > +t3u =3D LD80C(0x97213c6e35e119ff, -3, -1.47587722994530691476e-01L), > +t4u =3D LD80C(0x845a14a6a81dc94b, -4, 6.46249402389135358063e-02L), > +t5u =3D LD80C(0x864d46fa89997796, -5, -3.27885410884846056084e-02L), > +t6u =3D LD80C(0x93373cbd00297438, -6, 1.79706751150707171293e-02L), > +t7u =3D LD80C(0xa8fcfca7eddc8d1d, -7, -1.03142230361450732547e-02L), > +t8u =3D LD80C(0xc7e7015ff4bc45af, -8, 6.10053603296546099193e-03L), > +t9u =3D LD80C(0xf178d2247adc5093, -9, -3.68456964904901200152e-03L), > +t10u =3D LD80C(0x94188d58f12e5e9f, -9, 2.25976420273774583089e-03L), > +t11u =3D LD80C(0xb7cbaef14e1406f1, -10, -1.40224943666225639823e-03L), > +t12u =3D LD80C(0xe63a671e6704ea4d, -11, 8.78250640744776944887e-04L), > +t13u =3D LD80C(0x914b6c9cae61783e, -11, -5.54255012657716808811e-04L), > +t14u =3D LD80C(0xb858f5bdb79276fe, -12, 3.51614951536825927370e-04L), > +t15u =3D LD80C(0xea73e744c34b9591, -13, -2.23591563824520112236e-04L), > +t16u =3D LD80C(0x99aeabb0d67ba835, -13, 1.46562869351659194136e-04L), > +t17u =3D LD80C(0xd7c6938325db2024, -14, -1.02889866046435680588e-04L), > +t18u =3D LD80C(0xe24cb1e3b0474775, -15, 5.39540265505221957652e-05L); > +#define tc (tcu.e) > +#define tf (tfu.e) > +#define tt (ttu.e) > +#define t0 (t0u.e) > +#define t1 (t1u.e) > +#define t2 (t2u.e) > +#define t3 (t3u.e) > +#define t4 (t4u.e) > +#define t5 (t5u.e) > +#define t6 (t6u.e) > +#define t7 (t7u.e) > +#define t8 (t8u.e) > +#define t9 (t9u.e) > +#define t10 (t10u.e) > +#define t11 (t11u.e) > +#define t12 (t12u.e) > +#define t13 (t13u.e) > +#define t14 (t14u.e) > +#define t15 (t15u.e) > +#define t16 (t16u.e) > +#define t17 (t17u.e) > +#define t18 (t18u.e) > +/* > + * Domain y in [-0.1, 0.232], range ~[-8.1938e-22, 8.3815e-22]: > + * |(lgamma(1 + y) + 0.5 * y) / y - u(y) / v(y)| < 2**-71.2 > + */ > +static const union IEEEl2bits > +u0u =3D LD80C(0x9e233f1bed863d27, -4, -7.72156649015328606095e-02L), > +u1u =3D LD80C(0x98280ee45e4ddd3d, -1, 5.94361239198682739769e-01L), > +u2u =3D LD80C(0xe330c8ead4130733, 0, 1.77492629495841234275e+00L), > +u3u =3D LD80C(0xd4a213f1a002ec52, 0, 1.66119622514818078064e+00L), > +u4u =3D LD80C(0xa5a9ca6f5bc62163, -1, 6.47122051417476492989e-01L), > +u5u =3D LD80C(0xc980e49cd5b019e6, -4, 9.83903751718671509455e-02L), > +u6u =3D LD80C(0xff636a8bdce7025b, -9, 3.89691687802305743450e-03L), > +v1u =3D LD80C(0xbd109c533a19fbf5, 1, 2.95413883330948556544e+00L), > +v2u =3D LD80C(0xd295cbf96f31f099, 1, 3.29039286955665403176e+00L), > +v3u =3D LD80C(0xdab8bcfee40496cb, 0, 1.70876276441416471410e+00L), > +v4u =3D LD80C(0xd2f2dc3638567e9f, -2, 4.12009126299534668571e-01L), > +v5u =3D LD80C(0xa07d9b0851070f41, -5, 3.91822868305682491442e-02L), > +v6u =3D LD80C(0xe3cd8318f7adb2c4, -11, 8.68998648222144351114e-04L); > +#define u0 (u0u.e) > +#define u1 (u1u.e) > +#define u2 (u2u.e) > +#define u3 (u3u.e) > +#define u4 (u4u.e) > +#define u5 (u5u.e) > +#define u6 (u6u.e) > +#define v1 (v1u.e) > +#define v2 (v2u.e) > +#define v3 (v3u.e) > +#define v4 (v4u.e) > +#define v5 (v5u.e) > +#define v6 (v6u.e) > +/* > + * Domain x in (2, 3], range ~[-3.3648e-22, 3.4416e-22]: > + * |(lgamma(y+2) - 0.5 * y) / y - s(y)/r(y)| < 2**-72.3 > + * with y =3D x - 2. > + */ > +static const union IEEEl2bits > +s0u =3D LD80C(0x9e233f1bed863d27, -4, -7.72156649015328606095e-02L), > +s1u =3D LD80C(0xd3ff0dcc7fa91f94, -3, 2.07027640921219389860e-01L), > +s2u =3D LD80C(0xb2bb62782478ef31, -2, 3.49085881391362090549e-01L), > +s3u =3D LD80C(0xb49f7438c4611a74, -3, 1.76389518704213357954e-01L), > +s4u =3D LD80C(0x9a957008fa27ecf9, -5, 3.77401710862930008071e-02L), > +s5u =3D LD80C(0xda9b389a6ca7a7ac, -9, 3.33566791452943399399e-03L), > +s6u =3D LD80C(0xbc7a2263faf59c14, -14, 8.98728786745638844395e-05L), > +r1u =3D LD80C(0xbf5cff5b11477d4d, 0, 1.49502555796294337722e+00L), > +r2u =3D LD80C(0xd9aec89de08e3da6, -1, 8.50323236984473285866e-01L), > +r3u =3D LD80C(0xeab7ae5057c443f9, -3, 2.29216312078225806131e-01L), > +r4u =3D LD80C(0xf29707d9bd2b1e37, -6, 2.96130326586640089145e-02L), > +r5u =3D LD80C(0xd376c2f09736c5a3, -10, 1.61334161411590662495e-03L), > +r6u =3D LD80C(0xc985983d0cd34e3d, -16, 2.40232770710953450636e-05L), > +r7u =3D LD80C(0xe5c7a4f7fc2ef13d, -25, -5.34997929289167573510e-08L); > +#define s0 (s0u.e) > +#define s1 (s1u.e) > +#define s2 (s2u.e) > +#define s3 (s3u.e) > +#define s4 (s4u.e) > +#define s5 (s5u.e) > +#define s6 (s6u.e) > +#define r1 (r1u.e) > +#define r2 (r2u.e) > +#define r3 (r3u.e) > +#define r4 (r4u.e) > +#define r5 (r5u.e) > +#define r6 (r6u.e) > +#define r7 (r7u.e) > +/* > + * Domain z in [8, 0x1p70], range ~[-3.0235e-22, 3.0563e-22]: > + * |lgamma(x) - (x - 0.5) * (log(x) - 1) - w(1/x)| < 2**-71.7 > + */ > +static const union IEEEl2bits > +w0u =3D LD80C(0xd67f1c864beb4a69, -2, 4.18938533204672741776e-01L), > +w1u =3D LD80C(0xaaaaaaaaaaaaaaa1, -4, 8.33333333333333332678e-02L), > +w2u =3D LD80C(0xb60b60b60b5491c9, -9, -2.77777777777760927870e-03L), > +w3u =3D LD80C(0xd00d00cf58aede4c, -11, 7.93650793490637233668e-04L), > +w4u =3D LD80C(0x9c09bf626783d4a5, -11, -5.95238023926039051268e-04L), > +w5u =3D LD80C(0xdca7cadc5baa517b, -11, 8.41733700408000822962e-04L), > +w6u =3D LD80C(0xfb060e361e1ffd07, -10, -1.91515849570245136604e-03L), > +w7u =3D LD80C(0xcbd5101bb58d1f2b, -8, 6.22046743903262649294e-03L), > +w8u =3D LD80C(0xad27a668d32c821b, -6, -2.11370706734662081843e-02L); > +#define w0 (w0u.e) > +#define w1 (w1u.e) > +#define w2 (w2u.e) > +#define w3 (w3u.e) > +#define w4 (w4u.e) > +#define w5 (w5u.e) > +#define w6 (w6u.e) > +#define w7 (w7u.e) > +#define w8 (w8u.e) > + > +static long double > +sin_pil(long double x) > +{ > + volatile long double vz; > + long double y,z; > + uint64_t n; > + uint16_t hx; > + > + y =3D -x; > + > + vz =3D y+0x1p63; > + z =3D vz-0x1p63; > + if (z =3D=3D y) > + return zero; > + > + vz =3D y+0x1p61; > + EXTRACT_LDBL80_WORDS(hx,n,vz); > + z =3D vz-0x1p61; > + if (z > y) { > + z -=3D 0.25; /* adjust to round down */ > + n--; > + } > + n &=3D 7; /* octant of y mod 2 */ > + y =3D y - z + n * 0.25; /* y mod 2 */ > + > + switch (n) { > + case 0: y =3D __kernel_sinl(pi*y,zero,0); break; > + case 1: > + case 2: y =3D __kernel_cosl(pi*(0.5-y),zero); break; > + case 3: > + case 4: y =3D __kernel_sinl(pi*(one-y),zero,0); break; > + case 5: > + case 6: y =3D -__kernel_cosl(pi*(y-1.5),zero); break; > + default: y =3D __kernel_sinl(pi*(y-2.0),zero,0); break; > + } > + return -y; > +} > + > +long double > +lgammal_r(long double x, int *signgamp) > +{ > + long double nadj,p,p1,p2,q,r,t,w,y,z; > + uint64_t lx; > + int i; > + uint16_t hx,ix; > + > + EXTRACT_LDBL80_WORDS(hx,lx,x); > + > + /* purge +-Inf and NaNs */ > + *signgamp =3D 1; > + ix =3D hx&0x7fff; > + if(ix=3D=3D0x7fff) return x*x; > + > + ENTERI(); > + > + /* purge +-0 and tiny arguments */ > + *signgamp =3D 1-2*(hx>>15); > + if(ix<0x3fff-67) { /* |x|<2**-(p+3), return -log(|x|) = */ > + if((ix|lx)=3D=3D0) > + RETURNI(one/vzero); > + RETURNI(-logl(fabsl(x))); > + } > + > + /* purge negative integers and start evaluation for other x < 0 */ > + if(hx&0x8000) { > + *signgamp =3D 1; > + if(ix>=3D0x3fff+63) /* |x|>=3D2**(p-1), must be -inte= ger */ > + RETURNI(one/vzero); > + t =3D sin_pil(x); > + if(t=3D=3Dzero) RETURNI(one/vzero); /* -integer */ > + nadj =3D logl(pi/fabsl(t*x)); > + if(t + x =3D -x; > + } > + > + /* purge 1 and 2 */ > + if((ix=3D=3D0x3fff || ix=3D=3D0x4000) && lx=3D=3D0x8000000000000000= ULL) r =3D 0; > + /* for x < 2.0 */ > + else if(ix<0x4000) { > + /* > + * XXX Supposedly, one can use the following information to replace = the > + * XXX FP rational expressions. A similar approach is appropriate > + * XXX for ld128, but one (may need?) needs to consider llx, too. > + * > + * 8.9999961853027344e-01 3ffe e666600000000000 > + * 7.3159980773925781e-01 3ffe bb4a200000000000 > + * 2.3163998126983643e-01 3ffc ed33080000000000 > + * 1.7316312789916992e+00 3fff dda6180000000000 > + * 1.2316322326660156e+00 3fff 9da6200000000000 > + */ > + if(x<8.9999961853027344e-01) { > + r =3D -logl(x); > + if(x>=3D7.3159980773925781e-01) {y =3D 1-x; i=3D 0;} > + else if(x>=3D2.3163998126983643e-01) {y=3D x-(tc-1); i=3D1;= } > + else {y =3D x; i=3D2;} > + } else { > + r =3D 0; > + if(x>=3D1.7316312789916992e+00) {y=3D2-x;i=3D0;} > + else if(x>=3D1.2316322326660156e+00) {y=3Dx-tc;i=3D1;} > + else {y=3Dx-1;i=3D2;} > + } > + switch(i) { > + case 0: > + z =3D y*y; > + p1 =3D a0+z*(a2+z*(a4+z*(a6+z*(a8+z*(a10+z*a12))))); > + p2 =3D z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*(a11+z*a13)))))); > + p =3D y*p1+p2; > + r +=3D p-y/2; break; > + case 1: > + p =3D t0+y*t1+tt+y*y*(t2+y*(t3+y*(t4+y*(t5+y*(t6+y*(t7+y*(t= 8+ > + y*(t9+y*(t10+y*(t11+y*(t12+y*(t13+y*(t14+y*(t15+y*(t16+ > + y*(t17+y*t18)))))))))))))))); > + r +=3D tf + p; break; > + case 2: > + p1 =3D y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*(u5+y*u6)))))); > + p2 =3D 1+y*(v1+y*(v2+y*(v3+y*(v4+y*(v5+y*v6))))); > + r +=3D p1/p2-y/2; > + } > + } > + /* x < 8.0 */ > + else if(ix<0x4002) { > + i =3D x; > + y =3D x-i; > + p =3D y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); > + q =3D 1+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*(r6+y*r7)))))); > + r =3D y/2+p/q; > + z =3D 1; /* lgamma(1+s) =3D log(s) + lgamma(s) */ > + switch(i) { > + case 7: z *=3D (y+6); /* FALLTHRU */ > + case 6: z *=3D (y+5); /* FALLTHRU */ > + case 5: z *=3D (y+4); /* FALLTHRU */ > + case 4: z *=3D (y+3); /* FALLTHRU */ > + case 3: z *=3D (y+2); /* FALLTHRU */ > + r +=3D logl(z); break; > + } > + /* 8.0 <=3D x < 2**(p+3) */ > + } else if (ix<0x3fff+67) { > + t =3D logl(x); > + z =3D one/x; > + y =3D z*z; > + w =3D w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*(w6+y*(w7+y*w8))))))); > + r =3D (x-half)*(t-one)+w; > + /* 2**(p+3) <=3D x <=3D inf */ > + } else > + r =3D x*(logl(x)-1); > + if(hx&0x8000) r =3D nadj - r; > + RETURNI(r); > +} > diff --git a/newlib/libm/ld80/e_powl.c b/newlib/libm/ld80/e_powl.c > new file mode 100644 > index 000000000..ea25354c2 > --- /dev/null > +++ b/newlib/libm/ld80/e_powl.c > @@ -0,0 +1,662 @@ > +/*- > + * Copyright (c) 2008 Stephen L. Moshier > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the abov= e > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANT= IES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE F= OR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGE= S > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT = OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > + > +#include "math_private.h" > + > +/* > + * Polynomial evaluator: > + * P[0] x^n + P[1] x^(n-1) + ... + P[n] > + */ > +static inline long double > +__polevll(long double x, long double *PP, int n) > +{ > + long double y; > + long double *P; > + > + P =3D PP; > + y =3D *P++; > + do { > + y =3D y * x + *P++; > + } while (--n); > + > + return (y); > +} > + > +/* > + * Polynomial evaluator: > + * x^n + P[0] x^(n-1) + P[1] x^(n-2) + ... + P[n] > + */ > +static inline long double > +__p1evll(long double x, long double *PP, int n) > +{ > + long double y; > + long double *P; > + > + P =3D PP; > + n -=3D 1; > + y =3D x + *P++; > + do { > + y =3D y * x + *P++; > + } while (--n); > + > + return (y); > +} > + > +/* powl.c > + * > + * Power function, long double precision > + * > + * > + * > + * SYNOPSIS: > + * > + * long double x, y, z, powl(); > + * > + * z =3D powl( x, y ); > + * > + * > + * > + * DESCRIPTION: > + * > + * Computes x raised to the yth power. Analytically, > + * > + * x**y =3D exp( y log(x) ). > + * > + * Following Cody and Waite, this program uses a lookup table > + * of 2**-i/32 and pseudo extended precision arithmetic to > + * obtain several extra bits of accuracy in both the logarithm > + * and the exponential. > + * > + * > + * > + * ACCURACY: > + * > + * The relative error of pow(x,y) can be estimated > + * by y dl ln(2), where dl is the absolute error of > + * the internally computed base 2 logarithm. At the ends > + * of the approximation interval the logarithm equal 1/32 > + * and its relative error is about 1 lsb =3D 1.1e-19. Hence > + * the predicted relative error in the result is 2.3e-21 y . > + * > + * Relative error: > + * arithmetic domain # trials peak rms > + * > + * IEEE +-1000 40000 2.8e-18 3.7e-19 > + * .001 < x < 1000, with log(x) uniformly distributed. > + * -1000 < y < 1000, y uniformly distributed. > + * > + * IEEE 0,8700 60000 6.5e-18 1.0e-18 > + * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed. > + * > + * > + * ERROR MESSAGES: > + * > + * message condition value returned > + * pow overflow x**y > MAXNUM INFINITY > + * pow underflow x**y < 1/MAXNUM 0.0 > + * pow domain x<0 and y noninteger 0.0 > + * > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > +#include > + > +#include "math_private.h" > + > +/* Table size */ > +#define NXT 32 > +/* log2(Table size) */ > +#define LNXT 5 > + > +/* log(1+x) =3D x - .5x^2 + x^3 * P(z)/Q(z) > + * on the domain 2^(-1/32) - 1 <=3D x <=3D 2^(1/32) - 1 > + */ > +static long double P[] =3D { > + 8.3319510773868690346226E-4L, > + 4.9000050881978028599627E-1L, > + 1.7500123722550302671919E0L, > + 1.4000100839971580279335E0L, > +}; > +static long double Q[] =3D { > +/* 1.0000000000000000000000E0L,*/ > + 5.2500282295834889175431E0L, > + 8.4000598057587009834666E0L, > + 4.2000302519914740834728E0L, > +}; > +/* A[i] =3D 2^(-i/32), rounded to IEEE long double precision. > + * If i is even, A[i] + B[i/2] gives additional accuracy. > + */ > +static long double A[33] =3D { > + 1.0000000000000000000000E0L, > + 9.7857206208770013448287E-1L, > + 9.5760328069857364691013E-1L, > + 9.3708381705514995065011E-1L, > + 9.1700404320467123175367E-1L, > + 8.9735453750155359320742E-1L, > + 8.7812608018664974155474E-1L, > + 8.5930964906123895780165E-1L, > + 8.4089641525371454301892E-1L, > + 8.2287773907698242225554E-1L, > + 8.0524516597462715409607E-1L, > + 7.8799042255394324325455E-1L, > + 7.7110541270397041179298E-1L, > + 7.5458221379671136985669E-1L, > + 7.3841307296974965571198E-1L, > + 7.2259040348852331001267E-1L, > + 7.0710678118654752438189E-1L, > + 6.9195494098191597746178E-1L, > + 6.7712777346844636413344E-1L, > + 6.6261832157987064729696E-1L, > + 6.4841977732550483296079E-1L, > + 6.3452547859586661129850E-1L, > + 6.2092890603674202431705E-1L, > + 6.0762367999023443907803E-1L, > + 5.9460355750136053334378E-1L, > + 5.8186242938878875689693E-1L, > + 5.6939431737834582684856E-1L, > + 5.5719337129794626814472E-1L, > + 5.4525386633262882960438E-1L, > + 5.3357020033841180906486E-1L, > + 5.2213689121370692017331E-1L, > + 5.1094857432705833910408E-1L, > + 5.0000000000000000000000E-1L, > +}; > +static long double B[17] =3D { > + 0.0000000000000000000000E0L, > + 2.6176170809902549338711E-20L, > +-1.0126791927256478897086E-20L, > + 1.3438228172316276937655E-21L, > + 1.2207982955417546912101E-20L, > +-6.3084814358060867200133E-21L, > + 1.3164426894366316434230E-20L, > +-1.8527916071632873716786E-20L, > + 1.8950325588932570796551E-20L, > + 1.5564775779538780478155E-20L, > + 6.0859793637556860974380E-21L, > +-2.0208749253662532228949E-20L, > + 1.4966292219224761844552E-20L, > + 3.3540909728056476875639E-21L, > +-8.6987564101742849540743E-22L, > +-1.2327176863327626135542E-20L, > + 0.0000000000000000000000E0L, > +}; > + > +/* 2^x =3D 1 + x P(x), > + * on the interval -1/32 <=3D x <=3D 0 > + */ > +static long double R[] =3D { > + 1.5089970579127659901157E-5L, > + 1.5402715328927013076125E-4L, > + 1.3333556028915671091390E-3L, > + 9.6181291046036762031786E-3L, > + 5.5504108664798463044015E-2L, > + 2.4022650695910062854352E-1L, > + 6.9314718055994530931447E-1L, > +}; > + > +#define douba(k) A[k] > +#define doubb(k) B[k] > +#define MEXP (NXT*16384.0L) > +/* The following if denormal numbers are supported, else -MEXP: */ > +#define MNEXP (-NXT*(16384.0L+64.0L)) > +/* log2(e) - 1 */ > +#define LOG2EA 0.44269504088896340735992L > + > +#define F W > +#define Fa Wa > +#define Fb Wb > +#define G W > +#define Ga Wa > +#define Gb u > +#define H W > +#define Ha Wb > +#define Hb Wb > + > +static const long double MAXLOGL =3D 1.1356523406294143949492E4L; > +static const long double MINLOGL =3D -1.13994985314888605586758E4L; > +static const long double LOGE2L =3D 6.9314718055994530941723E-1L; > +static volatile long double z; > +static long double w, W, Wa, Wb, ya, yb, u; > +static const long double huge =3D 0x1p10000L; > +#if 0 /* XXX Prevent gcc from erroneously constant folding this. */ > +static const long double twom10000 =3D 0x1p-10000L; > +#else > +static volatile long double twom10000 =3D 0x1p-10000L; > +#endif > + > +static long double reducl( long double ); > +static long double powil ( long double, int ); > + > +long double > +powl(long double x, long double y) > +{ > +/* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */ > +int i, nflg, iyflg, yoddint; > +long e; > + > +if( y =3D=3D 0.0L ) > + return( 1.0L ); > + > +if( x =3D=3D 1.0L ) > + return( 1.0L ); > + > +if( isnan(x) ) > + return ( nan_mix(x, y) ); > +if( isnan(y) ) > + return ( nan_mix(x, y) ); > + > +if( y =3D=3D 1.0L ) > + return( x ); > + > +if( !isfinite(y) && x =3D=3D -1.0L ) > + return( 1.0L ); > + > +if( y >=3D LDBL_MAX ) > + { > + if( x > 1.0L ) > + return( INFINITY ); > + if( x > 0.0L && x < 1.0L ) > + return( 0.0L ); > + if( x < -1.0L ) > + return( INFINITY ); > + if( x > -1.0L && x < 0.0L ) > + return( 0.0L ); > + } > +if( y <=3D -LDBL_MAX ) > + { > + if( x > 1.0L ) > + return( 0.0L ); > + if( x > 0.0L && x < 1.0L ) > + return( INFINITY ); > + if( x < -1.0L ) > + return( 0.0L ); > + if( x > -1.0L && x < 0.0L ) > + return( INFINITY ); > + } > +if( x >=3D LDBL_MAX ) > + { > + if( y > 0.0L ) > + return( INFINITY ); > + return( 0.0L ); > + } > + > +w =3D floorl(y); > +/* Set iyflg to 1 if y is an integer. */ > +iyflg =3D 0; > +if( w =3D=3D y ) > + iyflg =3D 1; > + > +/* Test for odd integer y. */ > +yoddint =3D 0; > +if( iyflg ) > + { > + ya =3D fabsl(y); > + ya =3D floorl(0.5L * ya); > + yb =3D 0.5L * fabsl(w); > + if( ya !=3D yb ) > + yoddint =3D 1; > + } > + > +if( x <=3D -LDBL_MAX ) > + { > + if( y > 0.0L ) > + { > + if( yoddint ) > + return( -INFINITY ); > + return( INFINITY ); > + } > + if( y < 0.0L ) > + { > + if( yoddint ) > + return( -0.0L ); > + return( 0.0 ); > + } > + } > + > + > +nflg =3D 0; /* flag =3D 1 if x<0 raised to integer power */ > +if( x <=3D 0.0L ) > + { > + if( x =3D=3D 0.0L ) > + { > + if( y < 0.0 ) > + { > + if( signbit(x) && yoddint ) > + return( -INFINITY ); > + return( INFINITY ); > + } > + if( y > 0.0 ) > + { > + if( signbit(x) && yoddint ) > + return( -0.0L ); > + return( 0.0 ); > + } > + if( y =3D=3D 0.0L ) > + return( 1.0L ); /* 0**0 */ > + else > + return( 0.0L ); /* 0**y */ > + } > + else > + { > + if( iyflg =3D=3D 0 ) > + return (x - x) / (x - x); /* (x<0)**(non-int) is Na= N */ > + nflg =3D 1; > + } > + } > + > +/* Integer power of an integer. */ > + > +if( iyflg ) > + { > + i =3D w; > + w =3D floorl(x); > + if( (w =3D=3D x) && (fabsl(y) < 32768.0) ) > + { > + w =3D powil( x, (int) y ); > + return( w ); > + } > + } > + > + > +if( nflg ) > + x =3D fabsl(x); > + > +/* separate significand from exponent */ > +x =3D frexpl( x, &i ); > +e =3D i; > + > +/* find significand in antilog table A[] */ > +i =3D 1; > +if( x <=3D douba(17) ) > + i =3D 17; > +if( x <=3D douba(i+8) ) > + i +=3D 8; > +if( x <=3D douba(i+4) ) > + i +=3D 4; > +if( x <=3D douba(i+2) ) > + i +=3D 2; > +if( x >=3D douba(1) ) > + i =3D -1; > +i +=3D 1; > + > + > +/* Find (x - A[i])/A[i] > + * in order to compute log(x/A[i]): > + * > + * log(x) =3D log( a x/a ) =3D log(a) + log(x/a) > + * > + * log(x/a) =3D log(1+v), v =3D x/a - 1 =3D (x-a)/a > + */ > +x -=3D douba(i); > +x -=3D doubb(i/2); > +x /=3D douba(i); > + > + > +/* rational approximation for log(1+v): > + * > + * log(1+v) =3D v - v**2/2 + v**3 P(v) / Q(v) > + */ > +z =3D x*x; > +w =3D x * ( z * __polevll( x, P, 3 ) / __p1evll( x, Q, 3 ) ); > +w =3D w - ldexpl( z, -1 ); /* w - 0.5 * z */ > + > +/* Convert to base 2 logarithm: > + * multiply by log2(e) =3D 1 + LOG2EA > + */ > +z =3D LOG2EA * w; > +z +=3D w; > +z +=3D LOG2EA * x; > +z +=3D x; > + > +/* Compute exponent term of the base 2 logarithm. */ > +w =3D -i; > +w =3D ldexpl( w, -LNXT ); /* divide by NXT */ > +w +=3D e; > +/* Now base 2 log of x is w + z. */ > + > +/* Multiply base 2 log by y, in extended precision. */ > + > +/* separate y into large part ya > + * and small part yb less than 1/NXT > + */ > +ya =3D reducl(y); > +yb =3D y - ya; > + > +/* (w+z)(ya+yb) > + * =3D w*ya + w*yb + z*y > + */ > +F =3D z * y + w * yb; > +Fa =3D reducl(F); > +Fb =3D F - Fa; > + > +G =3D Fa + w * ya; > +Ga =3D reducl(G); > +Gb =3D G - Ga; > + > +H =3D Fb + Gb; > +Ha =3D reducl(H); > +w =3D ldexpl( Ga+Ha, LNXT ); > + > +/* Test the power of 2 for overflow */ > +if( w > MEXP ) > + return (huge * huge); /* overflow */ > + > +if( w < MNEXP ) > + return (twom10000 * twom10000); /* underflow */ > + > +e =3D w; > +Hb =3D H - Ha; > + > +if( Hb > 0.0L ) > + { > + e +=3D 1; > + Hb -=3D (1.0L/NXT); /*0.0625L;*/ > + } > + > +/* Now the product y * log2(x) =3D Hb + e/NXT. > + * > + * Compute base 2 exponential of Hb, > + * where -0.0625 <=3D Hb <=3D 0. > + */ > +z =3D Hb * __polevll( Hb, R, 6 ); /* z =3D 2**Hb - 1 */ > + > +/* Express e/NXT as an integer plus a negative number of (1/NXT)ths. > + * Find lookup table entry for the fractional power of 2. > + */ > +if( e < 0 ) > + i =3D 0; > +else > + i =3D 1; > +i =3D e/NXT + i; > +e =3D NXT*i - e; > +w =3D douba( e ); > +z =3D w * z; /* 2**-e * ( 1 + (2**Hb-1) ) */ > +z =3D z + w; > +z =3D ldexpl( z, i ); /* multiply by integer power of 2 */ > + > +if( nflg ) > + { > +/* For negative x, > + * find out if the integer exponent > + * is odd or even. > + */ > + w =3D ldexpl( y, -1 ); > + w =3D floorl(w); > + w =3D ldexpl( w, 1 ); > + if( w !=3D y ) > + z =3D -z; /* odd exponent */ > + } > + > +return( z ); > +} > + > + > +/* Find a multiple of 1/NXT that is within 1/NXT of x. */ > +static inline long double > +reducl(long double x) > +{ > +long double t; > + > +t =3D ldexpl( x, LNXT ); > +t =3D floorl( t ); > +t =3D ldexpl( t, -LNXT ); > +return(t); > +} > + > +/* powil.c > + * > + * Real raised to integer power, long double precision > + * > + * > + * > + * SYNOPSIS: > + * > + * long double x, y, powil(); > + * int n; > + * > + * y =3D powil( x, n ); > + * > + * > + * > + * DESCRIPTION: > + * > + * Returns argument x raised to the nth power. > + * The routine efficiently decomposes n as a sum of powers of > + * two. The desired power is a product of two-to-the-kth > + * powers of x. Thus to compute the 32767 power of x requires > + * 28 multiplications instead of 32767 multiplications. > + * > + * > + * > + * ACCURACY: > + * > + * > + * Relative error: > + * arithmetic x domain n domain # trials peak rms > + * IEEE .001,1000 -1022,1023 50000 4.3e-17 7.8e-18 > + * IEEE 1,2 -1022,1023 20000 3.9e-17 7.6e-18 > + * IEEE .99,1.01 0,8700 10000 3.6e-16 7.2e-17 > + * > + * Returns MAXNUM on overflow, zero on underflow. > + * > + */ > + > +static long double > +powil(long double x, int nn) > +{ > +long double ww, y; > +long double s; > +int n, e, sign, asign, lx; > + > +if( x =3D=3D 0.0L ) > + { > + if( nn =3D=3D 0 ) > + return( 1.0L ); > + else if( nn < 0 ) > + return( LDBL_MAX ); > + else > + return( 0.0L ); > + } > + > +if( nn =3D=3D 0 ) > + return( 1.0L ); > + > + > +if( x < 0.0L ) > + { > + asign =3D -1; > + x =3D -x; > + } > +else > + asign =3D 0; > + > + > +if( nn < 0 ) > + { > + sign =3D -1; > + n =3D -nn; > + } > +else > + { > + sign =3D 1; > + n =3D nn; > + } > + > +/* Overflow detection */ > + > +/* Calculate approximate logarithm of answer */ > +s =3D x; > +s =3D frexpl( s, &lx ); > +e =3D (lx - 1)*n; > +if( (e =3D=3D 0) || (e > 64) || (e < -64) ) > + { > + s =3D (s - 7.0710678118654752e-1L) / (s + 7.0710678118654752e-1L); > + s =3D (2.9142135623730950L * s - 0.5L + lx) * nn * LOGE2L; > + } > +else > + { > + s =3D LOGE2L * e; > + } > + > +if( s > MAXLOGL ) > + return (huge * huge); /* overflow */ > + > +if( s < MINLOGL ) > + return (twom10000 * twom10000); /* underflow */ > +/* Handle tiny denormal answer, but with less accuracy > + * since roundoff error in 1.0/x will be amplified. > + * The precise demarcation should be the gradual underflow threshold. > + */ > +if( s < (-MAXLOGL+2.0L) ) > + { > + x =3D 1.0L/x; > + sign =3D -sign; > + } > + > +/* First bit of the power */ > +if( n & 1 ) > + y =3D x; > + > +else > + { > + y =3D 1.0L; > + asign =3D 0; > + } > + > +ww =3D x; > +n >>=3D 1; > +while( n ) > + { > + ww =3D ww * ww; /* arg to the 2-to-the-kth power */ > + if( n & 1 ) /* if that bit is set, then include in product */ > + y *=3D ww; > + n >>=3D 1; > + } > + > +if( asign ) > + y =3D -y; /* odd power of negative number */ > +if( sign < 0 ) > + y =3D 1.0L/y; > +return(y); > +} > diff --git a/newlib/libm/ld80/e_rem_pio2l.h b/newlib/libm/ld80/e_rem_pio2= l.h > new file mode 100644 > index 000000000..b7ef5d983 > --- /dev/null > +++ b/newlib/libm/ld80/e_rem_pio2l.h > @@ -0,0 +1,143 @@ > +/* From: @(#)e_rem_pio2.c 1.4 95/01/18 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * > + * Optimized by Bruce D. Evans. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* ld80 version of __ieee754_rem_pio2l(x,y) > + * > + * return the remainder of x rem pi/2 in y[0]+y[1] > + * use __kernel_rem_pio2() > + */ > + > +#include > + > +#include "math.h" > +#include "math_private.h" > +#include "../ld/fpmath.h" > + > +#define BIAS (LDBL_MAX_EXP - 1) > + > +/* > + * invpio2: 64 bits of 2/pi > + * pio2_1: first 39 bits of pi/2 > + * pio2_1t: pi/2 - pio2_1 > + * pio2_2: second 39 bits of pi/2 > + * pio2_2t: pi/2 - (pio2_1+pio2_2) > + * pio2_3: third 39 bits of pi/2 > + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) > + */ > + > +static const double > +zero =3D 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ > +two24 =3D 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ > +pio2_1 =3D 1.57079632679597125389e+00, /* 0x3FF921FB, 0x54444000= */ > +pio2_2 =3D -1.07463465549783099519e-12, /* -0x12e7b967674000.0p-9= 2 */ > +pio2_3 =3D 6.36831716351370313614e-25; /* 0x18a2e037074000.0p-1= 33 */ > + > +#if defined(__amd64__) || defined(__i386__) > +/* Long double constants are slow on these arches, and broken on i386. *= / > +static const volatile double > +invpio2hi =3D 6.3661977236758138e-01, /* 0x145f306dc9c883.0p-53 */ > +invpio2lo =3D -3.9356538861223811e-17, /* -0x16b00000000000.0p-107 */ > +pio2_1thi =3D -1.0746346554971943e-12, /* -0x12e7b9676733af.0p-92 */ > +pio2_1tlo =3D 8.8451028997905949e-29, /* 0x1c080000000000.0p-146 */ > +pio2_2thi =3D 6.3683171635109499e-25, /* 0x18a2e03707344a.0p-133 */ > +pio2_2tlo =3D 2.3183081793789774e-41, /* 0x10280000000000.0p-187 */ > +pio2_3thi =3D -2.7529965190440717e-37, /* -0x176b7ed8fbbacc.0p-174 */ > +pio2_3tlo =3D -4.2006647512740502e-54; /* -0x19c00000000000.0p-230 */ > +#define invpio2 ((long double)invpio2hi + invpio2lo) > +#define pio2_1t ((long double)pio2_1thi + pio2_1tlo) > +#define pio2_2t ((long double)pio2_2thi + pio2_2tlo) > +#define pio2_3t ((long double)pio2_3thi + pio2_3tlo) > +#else > +static const long double > +invpio2 =3D 6.36619772367581343076e-01L, /* 0xa2f9836e4e44152a.0p= -64 */ > +pio2_1t =3D -1.07463465549719416346e-12L, /* -0x973dcb3b399d747f.0p= -103 */ > +pio2_2t =3D 6.36831716351095013979e-25L, /* 0xc51701b839a25205.0p= -144 */ > +pio2_3t =3D -2.75299651904407171810e-37L; /* -0xbb5bf6c7ddd660ce.0p= -185 */ > +#endif > + > +static inline __always_inline int > +__ieee754_rem_pio2l(long double x, long double *y) > +{ > + union IEEEl2bits u,u1; > + long double z,w,t,r,fn; > + double tx[3],ty[2]; > + int e0,ex,i,j,nx,n; > + int16_t expsign; > + > + u.e =3D x; > + expsign =3D u.xbits.expsign; > + ex =3D expsign & 0x7fff; > + if (ex < BIAS + 25 || (ex =3D=3D BIAS + 25 && u.bits.manh < 0xc90fd= aa2)) { > + /* |x| ~< 2^25*(pi/2), medium size */ > + fn =3D rnintl(x*invpio2); > + n =3D irint(fn); > + r =3D x-fn*pio2_1; > + w =3D fn*pio2_1t; /* 1st round good to 102 bit */ > + { > + union IEEEl2bits u2; > + int ex1; > + j =3D ex; > + y[0] =3D r-w; > + u2.e =3D y[0]; > + ex1 =3D u2.xbits.expsign & 0x7fff; > + i =3D j-ex1; > + if(i>22) { /* 2nd iteration needed, good to 141 */ > + t =3D r; > + w =3D fn*pio2_2; > + r =3D t-w; > + w =3D fn*pio2_2t-((t-r)-w); > + y[0] =3D r-w; > + u2.e =3D y[0]; > + ex1 =3D u2.xbits.expsign & 0x7fff; > + i =3D j-ex1; > + if(i>61) { /* 3rd iteration need, 180 bits acc */ > + t =3D r; /* will cover all possible cases */ > + w =3D fn*pio2_3; > + r =3D t-w; > + w =3D fn*pio2_3t-((t-r)-w); > + y[0] =3D r-w; > + } > + } > + } > + y[1] =3D (r-y[0])-w; > + return n; > + } > + /* > + * all other (large) arguments > + */ > + if(ex=3D=3D0x7fff) { /* x is inf or NaN */ > + y[0]=3Dy[1]=3Dx-x; return 0; > + } > + /* set z =3D scalbn(|x|,ilogb(x)-23) */ > + u1.e =3D x; > + e0 =3D ex - BIAS - 23; /* e0 =3D ilogb(|x|)-23; */ > + u1.xbits.expsign =3D ex - e0; > + z =3D u1.e; > + for(i=3D0;i<2;i++) { > + tx[i] =3D (double)((int32_t)(z)); > + z =3D (z-tx[i])*two24; > + } > + tx[2] =3D z; > + nx =3D 3; > + while(tx[nx-1]=3D=3Dzero) nx--; /* skip zero term */ > + n =3D __kernel_rem_pio2(tx,ty,e0,nx,2); > + r =3D (long double)ty[0] + ty[1]; > + w =3D ty[1] - (r - ty[0]); > + if(expsign<0) {y[0] =3D -r; y[1] =3D -w; return -n;} > + y[0] =3D r; y[1] =3D w; return n; > +} > diff --git a/newlib/libm/ld80/invtrig.c b/newlib/libm/ld80/invtrig.c > new file mode 100644 > index 000000000..5c8047857 > --- /dev/null > +++ b/newlib/libm/ld80/invtrig.c > @@ -0,0 +1,84 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2008 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include "invtrig.h" > + > +/* > + * asinl() and acosl() > + */ > +const long double > +pS0 =3D 1.66666666666666666631e-01L, > +pS1 =3D -4.16313987993683104320e-01L, > +pS2 =3D 3.69068046323246813704e-01L, > +pS3 =3D -1.36213932016738603108e-01L, > +pS4 =3D 1.78324189708471965733e-02L, > +pS5 =3D -2.19216428382605211588e-04L, > +pS6 =3D -7.10526623669075243183e-06L, > +qS1 =3D -2.94788392796209867269e+00L, > +qS2 =3D 3.27309890266528636716e+00L, > +qS3 =3D -1.68285799854822427013e+00L, > +qS4 =3D 3.90699412641738801874e-01L, > +qS5 =3D -3.14365703596053263322e-02L; > + > +/* > + * atanl() > + */ > +const long double atanhi[] =3D { > + 4.63647609000806116202e-01L, > + 7.85398163397448309628e-01L, > + 9.82793723247329067960e-01L, > + 1.57079632679489661926e+00L, > +}; > + > +const long double atanlo[] =3D { > + 1.18469937025062860669e-20L, > + -1.25413940316708300586e-20L, > + 2.55232234165405176172e-20L, > + -2.50827880633416601173e-20L, > +}; > + > +const long double aT[] =3D { > + 3.33333333333333333017e-01L, > + -1.99999999999999632011e-01L, > + 1.42857142857046531280e-01L, > + -1.11111111100562372733e-01L, > + 9.09090902935647302252e-02L, > + -7.69230552476207730353e-02L, > + 6.66661718042406260546e-02L, > + -5.88158892835030888692e-02L, > + 5.25499891539726639379e-02L, > + -4.70119845393155721494e-02L, > + 4.03539201366454414072e-02L, > + -2.91303858419364158725e-02L, > + 1.24822046299269234080e-02L, > +}; > + > +const long double pi_lo =3D -5.01655761266833202345e-20L; > diff --git a/newlib/libm/ld80/invtrig.h b/newlib/libm/ld80/invtrig.h > new file mode 100644 > index 000000000..be06a044b > --- /dev/null > +++ b/newlib/libm/ld80/invtrig.h > @@ -0,0 +1,116 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2008 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + * > + * $FreeBSD$ > + */ > + > +#include > + > +#include "fpmath.h" > + > +#define BIAS (LDBL_MAX_EXP - 1) > +#define MANH_SIZE LDBL_MANH_SIZE > + > +/* Approximation thresholds. */ > +#define ASIN_LINEAR (BIAS - 32) /* 2**-32 */ > +#define ACOS_CONST (BIAS - 65) /* 2**-65 */ > +#define ATAN_CONST (BIAS + 65) /* 2**65 */ > +#define ATAN_LINEAR (BIAS - 32) /* 2**-32 */ > + > +/* 0.95 */ > +#define THRESH ((0xe666666666666666ULL>>(64-(MANH_SIZE-1)))|LDBL_N= BIT) > + > +/* Constants shared by the long double inverse trig functions. */ > +#define pS0 _ItL_pS0 > +#define pS1 _ItL_pS1 > +#define pS2 _ItL_pS2 > +#define pS3 _ItL_pS3 > +#define pS4 _ItL_pS4 > +#define pS5 _ItL_pS5 > +#define pS6 _ItL_pS6 > +#define qS1 _ItL_qS1 > +#define qS2 _ItL_qS2 > +#define qS3 _ItL_qS3 > +#define qS4 _ItL_qS4 > +#define qS5 _ItL_qS5 > +#define atanhi _ItL_atanhi > +#define atanlo _ItL_atanlo > +#define aT _ItL_aT > +#define pi_lo _ItL_pi_lo > + > +#define pio2_hi atanhi[3] > +#define pio2_lo atanlo[3] > +#define pio4_hi atanhi[1] > + > +#ifdef STRUCT_DECLS > +typedef struct longdouble { > + uint64_t mant; > + uint16_t expsign; > +} LONGDOUBLE; > +#else > +typedef long double LONGDOUBLE; > +#endif > + > +extern const LONGDOUBLE pS0, pS1, pS2, pS3, pS4, pS5, pS6; > +extern const LONGDOUBLE qS1, qS2, qS3, qS4, qS5; > +extern const LONGDOUBLE atanhi[], atanlo[], aT[]; > +extern const LONGDOUBLE pi_lo; > + > +#ifndef STRUCT_DECLS > + > +static inline long double > +P(long double x) > +{ > + > + return (x * (pS0 + x * (pS1 + x * (pS2 + x * (pS3 + x * \ > + (pS4 + x * (pS5 + x * pS6))))))); > +} > + > +static inline long double > +Q(long double x) > +{ > + > + return (1.0 + x * (qS1 + x * (qS2 + x * (qS3 + x * (qS4 + x * qS5))= ))); > +} > + > +static inline long double > +T_even(long double x) > +{ > + > + return (aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] + x * \ > + (aT[8] + x * (aT[10] + x * aT[12])))))); > +} > + > +static inline long double > +T_odd(long double x) > +{ > + > + return (aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] + x * \ > + (aT[9] + x * aT[11]))))); > +} > + > +#endif > diff --git a/newlib/libm/ld80/k_cosl.c b/newlib/libm/ld80/k_cosl.c > new file mode 100644 > index 000000000..6dde6adad > --- /dev/null > +++ b/newlib/libm/ld80/k_cosl.c > @@ -0,0 +1,78 @@ > +/* From: @(#)k_cos.c 1.3 95/01/18 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * ld80 version of k_cos.c. See ../src/k_cos.c for most comments. > + */ > + > +#include "math_private.h" > + > +/* > + * Domain [-0.7854, 0.7854], range ~[-2.43e-23, 2.425e-23]: > + * |cos(x) - c(x)| < 2**-75.1 > + * > + * The coefficients of c(x) were generated by a pari-gp script using > + * a Remez algorithm that searches for the best higher coefficients > + * after rounding leading coefficients to a specified precision. > + * > + * Simpler methods like Chebyshev or basic Remez barely suffice for > + * cos() in 64-bit precision, because we want the coefficient of x^2 > + * to be precisely -0.5 so that multiplying by it is exact, and plain > + * rounding of the coefficients of a good polynomial approximation only > + * gives this up to about 64-bit precision. Plain rounding also gives > + * a mediocre approximation for the coefficient of x^4, but a rounding > + * error of 0.5 ulps for this coefficient would only contribute ~0.01 > + * ulps to the final error, so this is unimportant. Rounding errors in > + * higher coefficients are even less important. > + * > + * In fact, coefficients above the x^4 one only need to have 53-bit > + * precision, and this is more efficient. We get this optimization > + * almost for free from the complications needed to search for the best > + * higher coefficients. > + */ > +static const double > +one =3D 1.0; > + > +#if defined(__amd64__) || defined(__i386__) > +/* Long double constants are slow on these arches, and broken on i386. *= / > +static const volatile double > +C1hi =3D 0.041666666666666664, /* 0x15555555555555.0p-57 */ > +C1lo =3D 2.2598839032744733e-18; /* 0x14d80000000000.0p-1= 11 */ > +#define C1 ((long double)C1hi + C1lo) > +#else > +static const long double > +C1 =3D 0.0416666666666666666136L; /* 0xaaaaaaaaaaaaaa9b.0p-68 */ > +#endif > + > +static const double > +C2 =3D -0.0013888888888888874, /* -0x16c16c16c16c10.0p-62 */ > +C3 =3D 0.000024801587301571716, /* 0x1a01a01a018e22.0p-6= 8 */ > +C4 =3D -0.00000027557319215507120, /* -0x127e4fb7602f22.0p-74 */ > +C5 =3D 0.0000000020876754400407278, /* 0x11eed8caaeccf1.0p-81 */ > +C6 =3D -1.1470297442401303e-11, /* -0x19393412bd1529.0p-8= 9 */ > +C7 =3D 4.7383039476436467e-14; /* 0x1aac9d9af5c43e.0p-9= 7 */ > + > +long double > +__kernel_cosl(long double x, long double y) > +{ > + long double hz,z,r,w; > + > + z =3D x*x; > + r =3D z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*C7)))))); > + hz =3D 0.5*z; > + w =3D one-hz; > + return w + (((one-w)-hz) + (z*r-x*y)); > +} > diff --git a/newlib/libm/ld80/k_cospil.h b/newlib/libm/ld80/k_cospil.h > new file mode 100644 > index 000000000..6e13ef02a > --- /dev/null > +++ b/newlib/libm/ld80/k_cospil.h > @@ -0,0 +1,42 @@ > +/*- > + * Copyright (c) 2017 Steven G. Kargl > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice unmodified, this list of conditions, and the following > + * disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +/* > + * See ../src/k_cospi.c for implementation details. > + */ > + > +static inline long double > +__kernel_cospil(long double x) > +{ > + long double hi, lo; > + > + hi =3D (float)x; > + lo =3D x - hi; > + lo =3D lo * (pi_lo + pi_hi) + hi * pi_lo; > + hi *=3D pi_hi; > + _2sumF(hi, lo); > + return (__kernel_cosl(hi, lo)); > +} > diff --git a/newlib/libm/ld80/k_expl.h b/newlib/libm/ld80/k_expl.h > new file mode 100644 > index 000000000..a744d2d38 > --- /dev/null > +++ b/newlib/libm/ld80/k_expl.h > @@ -0,0 +1,301 @@ > +/* from: FreeBSD: head/lib/msun/ld80/s_expl.c 251343 2013-06-03 19:51:32= Z kargl */ > + > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2009-2013 Steven G. Kargl > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice unmodified, this list of conditions, and the following > + * disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + * > + * Optimized by Bruce D. Evans. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See s_expl.c for more comments about __k_expl(). > + * > + * See ../src/e_exp.c and ../src/k_exp.h for precision-independent comme= nts > + * about the secondary kernels. > + */ > + > +#define INTERVALS 128 > +#define LOG2_INTERVALS 7 > +#define BIAS (LDBL_MAX_EXP - 1) > + > +static const double > +/* > + * ln2/INTERVALS =3D L1+L2 (hi+lo decomposition for multiplication). L1= must > + * have at least 22 (=3D log2(|LDBL_MIN_EXP-extras|) + log2(INTERVALS)) = lowest > + * bits zero so that multiplication of it by n is exact. > + */ > +INV_L =3D 1.8466496523378731e+2, /* 0x171547652b82fe.0p-4= 5 */ > +L1 =3D 5.4152123484527692e-3, /* 0x162e42ff000000.0p-60 */ > +L2 =3D -3.2819649005320973e-13, /* -0x1718432a1b0e26.0p-9= 4 */ > +/* > + * Domain [-0.002708, 0.002708], range ~[-5.7136e-24, 5.7110e-24]: > + * |exp(x) - p(x)| < 2**-77.2 > + * (0.002708 is ln2/(2*INTERVALS) rounded up a little). > + */ > +A2 =3D 0.5, > +A3 =3D 1.6666666666666119e-1, /* 0x15555555555490.0p-55 */ > +A4 =3D 4.1666666666665887e-2, /* 0x155555555554e5.0p-57 */ > +A5 =3D 8.3333354987869413e-3, /* 0x1111115b789919.0p-59 */ > +A6 =3D 1.3888891738560272e-3; /* 0x16c16c651633ae.0p-62 */ > + > +/* > + * 2^(i/INTERVALS) for i in [0,INTERVALS] is represented by two values w= here > + * the first 53 bits of the significand are stored in hi and the next 53 > + * bits are in lo. Tang's paper states that the trailing 6 bits of hi m= ust > + * be zero for his algorithm in both single and double precision, becaus= e > + * the table is re-used in the implementation of expm1() where a floatin= g > + * point addition involving hi must be exact. Here hi is double, so > + * converting it to long double gives 11 trailing zero bits. > + */ > +static const struct { > + double hi; > + double lo; > +} tbl[INTERVALS] =3D { > + { 0x1p+0, 0x0p+0 }, > + /* > + * XXX hi is rounded down, and the formatting is not quite normal. > + * But I rather like both. The 0x1.*p format is good for 4N+1 > + * mantissa bits. Rounding down makes the lo terms positive, > + * so that the columnar formatting can be simpler. > + */ > + { 0x1.0163da9fb3335p+0, 0x1.b61299ab8cdb7p-54 }, > + { 0x1.02c9a3e778060p+0, 0x1.dcdef95949ef4p-53 }, > + { 0x1.04315e86e7f84p+0, 0x1.7ae71f3441b49p-53 }, > + { 0x1.059b0d3158574p+0, 0x1.d73e2a475b465p-55 }, > + { 0x1.0706b29ddf6ddp+0, 0x1.8db880753b0f6p-53 }, > + { 0x1.0874518759bc8p+0, 0x1.186be4bb284ffp-57 }, > + { 0x1.09e3ecac6f383p+0, 0x1.1487818316136p-54 }, > + { 0x1.0b5586cf9890fp+0, 0x1.8a62e4adc610bp-54 }, > + { 0x1.0cc922b7247f7p+0, 0x1.01edc16e24f71p-54 }, > + { 0x1.0e3ec32d3d1a2p+0, 0x1.03a1727c57b53p-59 }, > + { 0x1.0fb66affed31ap+0, 0x1.e464123bb1428p-53 }, > + { 0x1.11301d0125b50p+0, 0x1.49d77e35db263p-53 }, > + { 0x1.12abdc06c31cbp+0, 0x1.f72575a649ad2p-53 }, > + { 0x1.1429aaea92ddfp+0, 0x1.66820328764b1p-53 }, > + { 0x1.15a98c8a58e51p+0, 0x1.2406ab9eeab0ap-55 }, > + { 0x1.172b83c7d517ap+0, 0x1.b9bef918a1d63p-53 }, > + { 0x1.18af9388c8de9p+0, 0x1.777ee1734784ap-53 }, > + { 0x1.1a35beb6fcb75p+0, 0x1.e5b4c7b4968e4p-55 }, > + { 0x1.1bbe084045cd3p+0, 0x1.3563ce56884fcp-53 }, > + { 0x1.1d4873168b9aap+0, 0x1.e016e00a2643cp-54 }, > + { 0x1.1ed5022fcd91cp+0, 0x1.71033fec2243ap-53 }, > + { 0x1.2063b88628cd6p+0, 0x1.dc775814a8495p-55 }, > + { 0x1.21f49917ddc96p+0, 0x1.2a97e9494a5eep-55 }, > + { 0x1.2387a6e756238p+0, 0x1.9b07eb6c70573p-54 }, > + { 0x1.251ce4fb2a63fp+0, 0x1.ac155bef4f4a4p-55 }, > + { 0x1.26b4565e27cddp+0, 0x1.2bd339940e9d9p-55 }, > + { 0x1.284dfe1f56380p+0, 0x1.2d9e2b9e07941p-53 }, > + { 0x1.29e9df51fdee1p+0, 0x1.612e8afad1255p-55 }, > + { 0x1.2b87fd0dad98fp+0, 0x1.fbbd48ca71f95p-53 }, > + { 0x1.2d285a6e4030bp+0, 0x1.0024754db41d5p-54 }, > + { 0x1.2ecafa93e2f56p+0, 0x1.1ca0f45d52383p-56 }, > + { 0x1.306fe0a31b715p+0, 0x1.6f46ad23182e4p-55 }, > + { 0x1.32170fc4cd831p+0, 0x1.a9ce78e18047cp-55 }, > + { 0x1.33c08b26416ffp+0, 0x1.32721843659a6p-54 }, > + { 0x1.356c55f929ff0p+0, 0x1.928c468ec6e76p-53 }, > + { 0x1.371a7373aa9cap+0, 0x1.4e28aa05e8a8fp-53 }, > + { 0x1.38cae6d05d865p+0, 0x1.0b53961b37da2p-53 }, > + { 0x1.3a7db34e59ff6p+0, 0x1.d43792533c144p-53 }, > + { 0x1.3c32dc313a8e4p+0, 0x1.08003e4516b1ep-53 }, > + { 0x1.3dea64c123422p+0, 0x1.ada0911f09ebcp-55 }, > + { 0x1.3fa4504ac801bp+0, 0x1.417ee03548306p-53 }, > + { 0x1.4160a21f72e29p+0, 0x1.f0864b71e7b6cp-53 }, > + { 0x1.431f5d950a896p+0, 0x1.b8e088728219ap-53 }, > + { 0x1.44e086061892dp+0, 0x1.89b7a04ef80d0p-59 }, > + { 0x1.46a41ed1d0057p+0, 0x1.c944bd1648a76p-54 }, > + { 0x1.486a2b5c13cd0p+0, 0x1.3c1a3b69062f0p-56 }, > + { 0x1.4a32af0d7d3dep+0, 0x1.9cb62f3d1be56p-54 }, > + { 0x1.4bfdad5362a27p+0, 0x1.d4397afec42e2p-56 }, > + { 0x1.4dcb299fddd0dp+0, 0x1.8ecdbbc6a7833p-54 }, > + { 0x1.4f9b2769d2ca6p+0, 0x1.5a67b16d3540ep-53 }, > + { 0x1.516daa2cf6641p+0, 0x1.8225ea5909b04p-53 }, > + { 0x1.5342b569d4f81p+0, 0x1.be1507893b0d5p-53 }, > + { 0x1.551a4ca5d920ep+0, 0x1.8a5d8c4048699p-53 }, > + { 0x1.56f4736b527dap+0, 0x1.9bb2c011d93adp-54 }, > + { 0x1.58d12d497c7fdp+0, 0x1.295e15b9a1de8p-55 }, > + { 0x1.5ab07dd485429p+0, 0x1.6324c054647adp-54 }, > + { 0x1.5c9268a5946b7p+0, 0x1.c4b1b816986a2p-60 }, > + { 0x1.5e76f15ad2148p+0, 0x1.ba6f93080e65ep-54 }, > + { 0x1.605e1b976dc08p+0, 0x1.60edeb25490dcp-53 }, > + { 0x1.6247eb03a5584p+0, 0x1.63e1f40dfa5b5p-53 }, > + { 0x1.6434634ccc31fp+0, 0x1.8edf0e2989db3p-53 }, > + { 0x1.6623882552224p+0, 0x1.224fb3c5371e6p-53 }, > + { 0x1.68155d44ca973p+0, 0x1.038ae44f73e65p-57 }, > + { 0x1.6a09e667f3bccp+0, 0x1.21165f626cdd5p-53 }, > + { 0x1.6c012750bdabep+0, 0x1.daed533001e9ep-53 }, > + { 0x1.6dfb23c651a2ep+0, 0x1.e441c597c3775p-53 }, > + { 0x1.6ff7df9519483p+0, 0x1.9f0fc369e7c42p-53 }, > + { 0x1.71f75e8ec5f73p+0, 0x1.ba46e1e5de15ap-53 }, > + { 0x1.73f9a48a58173p+0, 0x1.7ab9349cd1562p-53 }, > + { 0x1.75feb564267c8p+0, 0x1.7edd354674916p-53 }, > + { 0x1.780694fde5d3fp+0, 0x1.866b80a02162dp-54 }, > + { 0x1.7a11473eb0186p+0, 0x1.afaa2047ed9b4p-53 }, > + { 0x1.7c1ed0130c132p+0, 0x1.f124cd1164dd6p-54 }, > + { 0x1.7e2f336cf4e62p+0, 0x1.05d02ba15797ep-56 }, > + { 0x1.80427543e1a11p+0, 0x1.6c1bccec9346bp-53 }, > + { 0x1.82589994cce12p+0, 0x1.159f115f56694p-53 }, > + { 0x1.8471a4623c7acp+0, 0x1.9ca5ed72f8c81p-53 }, > + { 0x1.868d99b4492ecp+0, 0x1.01c83b21584a3p-53 }, > + { 0x1.88ac7d98a6699p+0, 0x1.994c2f37cb53ap-54 }, > + { 0x1.8ace5422aa0dbp+0, 0x1.6e9f156864b27p-54 }, > + { 0x1.8cf3216b5448bp+0, 0x1.de55439a2c38bp-53 }, > + { 0x1.8f1ae99157736p+0, 0x1.5cc13a2e3976cp-55 }, > + { 0x1.9145b0b91ffc5p+0, 0x1.114c368d3ed6ep-53 }, > + { 0x1.93737b0cdc5e4p+0, 0x1.e8a0387e4a814p-53 }, > + { 0x1.95a44cbc8520ep+0, 0x1.d36906d2b41f9p-53 }, > + { 0x1.97d829fde4e4fp+0, 0x1.173d241f23d18p-53 }, > + { 0x1.9a0f170ca07b9p+0, 0x1.7462137188ce7p-53 }, > + { 0x1.9c49182a3f090p+0, 0x1.c7c46b071f2bep-56 }, > + { 0x1.9e86319e32323p+0, 0x1.824ca78e64c6ep-56 }, > + { 0x1.a0c667b5de564p+0, 0x1.6535b51719567p-53 }, > + { 0x1.a309bec4a2d33p+0, 0x1.6305c7ddc36abp-54 }, > + { 0x1.a5503b23e255cp+0, 0x1.1684892395f0fp-53 }, > + { 0x1.a799e1330b358p+0, 0x1.bcb7ecac563c7p-54 }, > + { 0x1.a9e6b5579fdbfp+0, 0x1.0fac90ef7fd31p-54 }, > + { 0x1.ac36bbfd3f379p+0, 0x1.81b72cd4624ccp-53 }, > + { 0x1.ae89f995ad3adp+0, 0x1.7a1cd345dcc81p-54 }, > + { 0x1.b0e07298db665p+0, 0x1.2108559bf8deep-53 }, > + { 0x1.b33a2b84f15fap+0, 0x1.ed7fa1cf7b290p-53 }, > + { 0x1.b59728de55939p+0, 0x1.1c7102222c90ep-53 }, > + { 0x1.b7f76f2fb5e46p+0, 0x1.d54f610356a79p-53 }, > + { 0x1.ba5b030a10649p+0, 0x1.0819678d5eb69p-53 }, > + { 0x1.bcc1e904bc1d2p+0, 0x1.23dd07a2d9e84p-55 }, > + { 0x1.bf2c25bd71e08p+0, 0x1.0811ae04a31c7p-53 }, > + { 0x1.c199bdd85529cp+0, 0x1.11065895048ddp-55 }, > + { 0x1.c40ab5fffd07ap+0, 0x1.b4537e083c60ap-54 }, > + { 0x1.c67f12e57d14bp+0, 0x1.2884dff483cadp-54 }, > + { 0x1.c8f6d9406e7b5p+0, 0x1.1acbc48805c44p-56 }, > + { 0x1.cb720dcef9069p+0, 0x1.503cbd1e949dbp-56 }, > + { 0x1.cdf0b555dc3f9p+0, 0x1.889f12b1f58a3p-53 }, > + { 0x1.d072d4a07897bp+0, 0x1.1a1e45e4342b2p-53 }, > + { 0x1.d2f87080d89f1p+0, 0x1.15bc247313d44p-53 }, > + { 0x1.d5818dcfba487p+0, 0x1.2ed02d75b3707p-55 }, > + { 0x1.d80e316c98397p+0, 0x1.7709f3a09100cp-53 }, > + { 0x1.da9e603db3285p+0, 0x1.c2300696db532p-54 }, > + { 0x1.dd321f301b460p+0, 0x1.2da5778f018c3p-54 }, > + { 0x1.dfc97337b9b5ep+0, 0x1.72d195873da52p-53 }, > + { 0x1.e264614f5a128p+0, 0x1.424ec3f42f5b5p-53 }, > + { 0x1.e502ee78b3ff6p+0, 0x1.39e8980a9cc8fp-55 }, > + { 0x1.e7a51fbc74c83p+0, 0x1.2d522ca0c8de2p-54 }, > + { 0x1.ea4afa2a490d9p+0, 0x1.0b1ee7431ebb6p-53 }, > + { 0x1.ecf482d8e67f0p+0, 0x1.1b60625f7293ap-53 }, > + { 0x1.efa1bee615a27p+0, 0x1.dc7f486a4b6b0p-54 }, > + { 0x1.f252b376bba97p+0, 0x1.3a1a5bf0d8e43p-54 }, > + { 0x1.f50765b6e4540p+0, 0x1.9d3e12dd8a18bp-54 }, > + { 0x1.f7bfdad9cbe13p+0, 0x1.1227697fce57bp-53 }, > + { 0x1.fa7c1819e90d8p+0, 0x1.74853f3a5931ep-55 }, > + { 0x1.fd3c22b8f71f1p+0, 0x1.2eb74966579e7p-57 } > +}; > + > +/* > + * Kernel for expl(x). x must be finite and not tiny or huge. > + * "tiny" is anything that would make us underflow (|A6*x^6| < ~LDBL_MIN= ). > + * "huge" is anything that would make fn*L1 inexact (|x| > ~2**17*ln2). > + */ > +static inline void > +__k_expl(long double x, long double *hip, long double *lop, int *kp) > +{ > + long double fn, q, r, r1, r2, t, z; > + int n, n2; > + > + /* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */ > + fn =3D rnintl(x * INV_L); > + r =3D x - fn * L1 - fn * L2; /* r =3D r1 + r2 done independent= ly. */ > + n =3D irint(fn); > + n2 =3D (unsigned)n % INTERVALS; > + /* Depend on the sign bit being propagated: */ > + *kp =3D n >> LOG2_INTERVALS; > + r1 =3D x - fn * L1; > + r2 =3D fn * -L2; > + > + /* Evaluate expl(endpoint[n2] + r1 + r2) =3D tbl[n2] * expl(r1 + r2= ). */ > + z =3D r * r; > +#if 0 > + q =3D r2 + z * (A2 + r * A3) + z * z * (A4 + r * A5) + z * z * z * = A6; > +#else > + q =3D r2 + z * A2 + z * r * (A3 + r * A4 + z * (A5 + r * A6)); > +#endif > + t =3D (long double)tbl[n2].lo + tbl[n2].hi; > + *hip =3D tbl[n2].hi; > + *lop =3D tbl[n2].lo + t * (q + r1); > +} > + > +static inline void > +k_hexpl(long double x, long double *hip, long double *lop) > +{ > + float twopkm1; > + int k; > + > + __k_expl(x, hip, lop, &k); > + SET_FLOAT_WORD(twopkm1, 0x3f800000 + ((k - 1) << 23)); > + *hip *=3D twopkm1; > + *lop *=3D twopkm1; > +} > + > +static inline long double > +hexpl(long double x) > +{ > + long double hi, lo, twopkm2; > + int k; > + > + twopkm2 =3D 1; > + __k_expl(x, &hi, &lo, &k); > + SET_LDBL_EXPSIGN(twopkm2, BIAS + k - 2); > + return (lo + hi) * 2 * twopkm2; > +} > + > +#ifdef _COMPLEX_H > +/* > + * See ../src/k_exp.c for details. > + */ > +static inline long double complex > +__ldexp_cexpl(long double complex z, int expt) > +{ > + long double c, exp_x, hi, lo, s; > + long double x, y, scale1, scale2; > + int half_expt, k; > + > + x =3D creall(z); > + y =3D cimagl(z); > + __k_expl(x, &hi, &lo, &k); > + > + exp_x =3D (lo + hi) * 0x1p16382L; > + expt +=3D k - 16382; > + > + scale1 =3D 1; > + half_expt =3D expt / 2; > + SET_LDBL_EXPSIGN(scale1, BIAS + half_expt); > + scale2 =3D 1; > + SET_LDBL_EXPSIGN(scale2, BIAS + expt - half_expt); > + > + sincosl(y, &s, &c); > + return (CMPLXL(c * exp_x * scale1 * scale2, > + s * exp_x * scale1 * scale2)); > +} > +#endif /* _COMPLEX_H */ > diff --git a/newlib/libm/ld80/k_sinl.c b/newlib/libm/ld80/k_sinl.c > new file mode 100644 > index 000000000..af5598dba > --- /dev/null > +++ b/newlib/libm/ld80/k_sinl.c > @@ -0,0 +1,62 @@ > +/* From: @(#)k_sin.c 1.3 95/01/18 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. > + * > + * Developed at SunSoft, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * ld80 version of k_sin.c. See ../src/k_sin.c for most comments. > + */ > + > +#include "math_private.h" > + > +static const double > +half =3D 0.5; > + > +/* > + * Domain [-0.7854, 0.7854], range ~[-1.89e-22, 1.915e-22] > + * |sin(x)/x - s(x)| < 2**-72.1 > + * > + * See ../ld80/k_cosl.c for more details about the polynomial. > + */ > +#if defined(__amd64__) || defined(__i386__) > +/* Long double constants are slow on these arches, and broken on i386. *= / > +static const volatile double > +S1hi =3D -0.16666666666666666, /* -0x15555555555555.0p-55 */ > +S1lo =3D -9.2563760475949941e-18; /* -0x15580000000000.0p-1= 09 */ > +#define S1 ((long double)S1hi + S1lo) > +#else > +static const long double > +S1 =3D -0.166666666666666666671L; /* -0xaaaaaaaaaaaaaaab.0p= -66 */ > +#endif > + > +static const double > +S2 =3D 0.0083333333333333332, /* 0x11111111111111.0p-59 */ > +S3 =3D -0.00019841269841269427, /* -0x1a01a01a019f81.0p-6= 5 */ > +S4 =3D 0.0000027557319223597490, /* 0x171de3a55560f7.0p-7= 1 */ > +S5 =3D -0.000000025052108218074604, /* -0x1ae64564f16cad.0p-78 */ > +S6 =3D 1.6059006598854211e-10, /* 0x161242b90243b5.0p-8= 5 */ > +S7 =3D -7.6429779983024564e-13, /* -0x1ae42ebd1b2e00.0p-9= 3 */ > +S8 =3D 2.6174587166648325e-15; /* 0x179372ea0b3f64.0p-1= 01 */ > + > +long double > +__kernel_sinl(long double x, long double y, int iy) > +{ > + long double z,r,v; > + > + z =3D x*x; > + v =3D z*x; > + r =3D S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*S8))))); > + if(iy=3D=3D0) return x+v*(S1+z*r); > + else return x-((z*(half*y-v*r)-y)-v*S1); > +} > diff --git a/newlib/libm/ld80/k_sinpil.h b/newlib/libm/ld80/k_sinpil.h > new file mode 100644 > index 000000000..00241b932 > --- /dev/null > +++ b/newlib/libm/ld80/k_sinpil.h > @@ -0,0 +1,42 @@ > +/*- > + * Copyright (c) 2017 Steven G. Kargl > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice unmodified, this list of conditions, and the following > + * disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +/* > + * See ../src/k_sinpi.c for implementation details. > + */ > + > +static inline long double > +__kernel_sinpil(long double x) > +{ > + long double hi, lo; > + > + hi =3D (float)x; > + lo =3D x - hi; > + lo =3D lo * (pi_lo + pi_hi) + hi * pi_lo; > + hi *=3D pi_hi; > + _2sumF(hi, lo); > + return (__kernel_sinl(hi, lo, 1)); > +} > diff --git a/newlib/libm/ld80/s_cospil.c b/newlib/libm/ld80/s_cospil.c > new file mode 100644 > index 000000000..199479e9e > --- /dev/null > +++ b/newlib/libm/ld80/s_cospil.c > @@ -0,0 +1,129 @@ > +/*- > + * Copyright (c) 2017 Steven G. Kargl > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice unmodified, this list of conditions, and the following > + * disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +/* > + * See ../src/s_cospi.c for implementation details. > + */ > + > +#ifdef __i386__ > +#include > +#endif > +#include > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +static const double > +pi_hi =3D 3.1415926814079285e+00, /* 0x400921fb 0x58000000 */ > +pi_lo =3D-2.7818135228334233e-08; /* 0xbe5dde97 0x3dcb3b3a */ > + > +#include "k_cospil.h" > +#include "k_sinpil.h" > + > +volatile static const double vzero =3D 0; > + > +long double > +cospil(long double x) > +{ > + long double ax, c; > + uint64_t lx, m; > + uint32_t j0; > + uint16_t hx, ix; > + > + EXTRACT_LDBL80_WORDS(hx, lx, x); > + ix =3D hx & 0x7fff; > + INSERT_LDBL80_WORDS(ax, ix, lx); > + > + ENTERI(); > + > + if (ix < 0x3fff) { /* |x| < 1 */ > + if (ix < 0x3ffd) { /* |x| < 0.25 */ > + if (ix < 0x3fdd) { /* |x| < 0x1p-34 */ > + if ((int)x =3D=3D 0) > + RETURNI(1); > + } > + RETURNI(__kernel_cospil(ax)); > + } > + > + if (ix < 0x3ffe) /* |x| < 0.5 */ > + c =3D __kernel_sinpil(0.5 - ax); > + else if (lx < 0xc000000000000000ull) { /* |x| < 0.75 */ > + if (ax =3D=3D 0.5) > + RETURNI(0); > + c =3D -__kernel_sinpil(ax - 0.5); > + } else > + c =3D -__kernel_cospil(1 - ax); > + RETURNI(c); > + } > + > + if (ix < 0x403e) { /* 1 <=3D |x| < 0x1p63 */ > + /* Determine integer part of ax. */ > + j0 =3D ix - 0x3fff + 1; > + if (j0 < 32) { > + lx =3D (lx >> 32) << 32; > + lx &=3D ~(((lx << 32)-1) >> j0); > + } else { > + m =3D (uint64_t)-1 >> (j0 + 1); > + if (lx & m) lx &=3D ~m; > + } > + INSERT_LDBL80_WORDS(x, ix, lx); > + > + ax -=3D x; > + EXTRACT_LDBL80_WORDS(ix, lx, ax); > + > + if (ix < 0x3ffe) { /* |x| < 0.5 */ > + if (ix < 0x3ffd) /* |x| < 0.25 */ > + c =3D ix =3D=3D 0 ? 1 : __kernel_cospil(ax)= ; > + else > + c =3D __kernel_sinpil(0.5 - ax); > + > + } else { > + if (lx < 0xc000000000000000ull) { /* |x| < 0.75 */ > + if (ax =3D=3D 0.5) > + RETURNI(0); > + c =3D -__kernel_sinpil(ax - 0.5); > + } else > + c =3D -__kernel_cospil(1 - ax); > + } > + > + if (j0 > 40) > + x -=3D 0x1p40; > + if (j0 > 30) > + x -=3D 0x1p30; > + j0 =3D (uint32_t)x; > + > + RETURNI(j0 & 1 ? -c : c); > + } > + > + if (ix >=3D 0x7fff) > + RETURNI(vzero / vzero); > + > + /* > + * |x| >=3D 0x1p63 is always an even integer, so return 1. > + */ > + RETURNI(1); > +} > diff --git a/newlib/libm/ld80/s_erfl.c b/newlib/libm/ld80/s_erfl.c > new file mode 100644 > index 000000000..1ae2f9092 > --- /dev/null > +++ b/newlib/libm/ld80/s_erfl.c > @@ -0,0 +1,337 @@ > +/* @(#)s_erf.c 5.1 93/09/24 */ > +/* > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. > + * > + * Developed at SunPro, a Sun Microsystems, Inc. business. > + * Permission to use, copy, modify, and distribute this > + * software is freely granted, provided that this notice > + * is preserved. > + * =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/* > + * See s_erf.c for complete comments. > + * > + * Converted to long double by Steven G. Kargl. > + */ > +#include > +#ifdef __i386__ > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +/* XXX Prevent compilers from erroneously constant folding: */ > +static const volatile long double tiny =3D 0x1p-10000L; > + > +static const double > +half=3D 0.5, > +one =3D 1, > +two =3D 2; > +/* > + * In the domain [0, 2**-34], only the first term in the power series > + * expansion of erf(x) is used. The magnitude of the first neglected > + * terms is less than 2**-102. > + */ > +static const union IEEEl2bits > +efxu =3D LD80C(0x8375d410a6db446c, -3, 1.28379167095512573902e-1L), > +efx8u =3D LD80C(0x8375d410a6db446c, 0, 1.02703333676410059122e+0L), > +/* > + * Domain [0, 0.84375], range ~[-1.423e-22, 1.423e-22]: > + * |(erf(x) - x)/x - pp(x)/qq(x)| < 2**-72.573 > + */ > +pp0u =3D LD80C(0x8375d410a6db446c, -3, 1.28379167095512573902e-1L), > +pp1u =3D LD80C(0xa46c7d09ec3d0cec, -2, -3.21140201054840180596e-1L), > +pp2u =3D LD80C(0x9b31e66325576f86, -5, -3.78893851760347812082e-2L), > +pp3u =3D LD80C(0x804ac72c9a0b97dd, -7, -7.83032847030604679616e-3L), > +pp4u =3D LD80C(0x9f42bcbc3d5a601d, -12, -3.03765663857082048459e-4L), > +pp5u =3D LD80C(0x9ec4ad6193470693, -16, -1.89266527398167917502e-5L), > +qq1u =3D LD80C(0xdb4b8eb713188d6b, -2, 4.28310832832310510579e-1L), > +qq2u =3D LD80C(0xa5750835b2459bd1, -4, 8.07896272074540216658e-2L), > +qq3u =3D LD80C(0x8b85d6bd6a90b51c, -7, 8.51579638189385354266e-3L), > +qq4u =3D LD80C(0x87332f82cff4ff96, -11, 5.15746855583604912827e-4L), > +qq5u =3D LD80C(0x83466cb6bf9dca00, -16, 1.56492109706256700009e-5L), > +qq6u =3D LD80C(0xf5bf98c2f996bf63, -24, 1.14435527803073879724e-7L); > +#define efx (efxu.e) > +#define efx8 (efx8u.e) > +#define pp0 (pp0u.e) > +#define pp1 (pp1u.e) > +#define pp2 (pp2u.e) > +#define pp3 (pp3u.e) > +#define pp4 (pp4u.e) > +#define pp5 (pp5u.e) > +#define qq1 (qq1u.e) > +#define qq2 (qq2u.e) > +#define qq3 (qq3u.e) > +#define qq4 (qq4u.e) > +#define qq5 (qq5u.e) > +#define qq6 (qq6u.e) > +static const union IEEEl2bits > +erxu =3D LD80C(0xd7bb3d0000000000, -1, 8.42700779438018798828e-1L), > +/* > + * Domain [0.84375, 1.25], range ~[-8.132e-22, 8.113e-22]: > + * |(erf(x) - erx) - pa(x)/qa(x)| < 2**-71.762 > + */ > +pa0u =3D LD80C(0xe8211158da02c692, -27, 1.35116960705131296711e-8L), > +pa1u =3D LD80C(0xd488f89f36988618, -2, 4.15107507167065612570e-1L), > +pa2u =3D LD80C(0xece74f8c63fa3942, -4, -1.15675565215949226989e-1L), > +pa3u =3D LD80C(0xc8d31e020727c006, -4, 9.80589241379624665791e-2L), > +pa4u =3D LD80C(0x985d5d5fafb0551f, -5, 3.71984145558422368847e-2L), > +pa5u =3D LD80C(0xa5b6c4854d2f5452, -8, -5.05718799340957673661e-3L), > +pa6u =3D LD80C(0x85c8d58fe3993a47, -8, 4.08277919612202243721e-3L), > +pa7u =3D LD80C(0xddbfbc23677b35cf, -13, 2.11476292145347530794e-4L), > +qa1u =3D LD80C(0xb8a977896f5eff3f, -1, 7.21335860303380361298e-1L), > +qa2u =3D LD80C(0x9fcd662c3d4eac86, -1, 6.24227891731886593333e-1L), > +qa3u =3D LD80C(0x9d0b618eac67ba07, -2, 3.06727455774491855801e-1L), > +qa4u =3D LD80C(0x881a4293f6d6c92d, -3, 1.32912674218195890535e-1L), > +qa5u =3D LD80C(0xbab144f07dea45bf, -5, 4.55792134233613027584e-2L), > +qa6u =3D LD80C(0xa6c34ba438bdc900, -7, 1.01783980070527682680e-2L), > +qa7u =3D LD80C(0x8fa866dc20717a91, -9, 2.19204436518951438183e-3L); > +#define erx (erxu.e) > +#define pa0 (pa0u.e) > +#define pa1 (pa1u.e) > +#define pa2 (pa2u.e) > +#define pa3 (pa3u.e) > +#define pa4 (pa4u.e) > +#define pa5 (pa5u.e) > +#define pa6 (pa6u.e) > +#define pa7 (pa7u.e) > +#define qa1 (qa1u.e) > +#define qa2 (qa2u.e) > +#define qa3 (qa3u.e) > +#define qa4 (qa4u.e) > +#define qa5 (qa5u.e) > +#define qa6 (qa6u.e) > +#define qa7 (qa7u.e) > +static const union IEEEl2bits > +/* > + * Domain [1.25,2.85715], range ~[-2.334e-22,2.334e-22]: > + * |log(x*erfc(x)) + x**2 + 0.5625 - ra(x)/sa(x)| < 2**-71.860 > + */ > +ra0u =3D LD80C(0xa1a091e0fb4f335a, -7, -9.86494298915814308249e-3L), > +ra1u =3D LD80C(0xc2b0d045ae37df6b, -1, -7.60510460864878271275e-1L), > +ra2u =3D LD80C(0xf2cec3ee7da636c5, 3, -1.51754798236892278250e+1L), > +ra3u =3D LD80C(0x813cc205395adc7d, 7, -1.29237335516455333420e+2L), > +ra4u =3D LD80C(0x8737c8b7b4062c2f, 9, -5.40871625829510494776e+2L), > +ra5u =3D LD80C(0x8ffe5383c08d4943, 10, -1.15194769466026108551e+3L), > +ra6u =3D LD80C(0x983573e64d5015a9, 10, -1.21767039790249025544e+3L), > +ra7u =3D LD80C(0x92a794e763a6d4db, 9, -5.86618463370624636688e+2L), > +ra8u =3D LD80C(0xd5ad1fae77c3d9a3, 6, -1.06838132335777049840e+2L), > +ra9u =3D LD80C(0x934c1a247807bb9c, 2, -4.60303980944467334806e+0L), > +sa1u =3D LD80C(0xd342f90012bb1189, 4, 2.64077014928547064865e+1L), > +sa2u =3D LD80C(0x839be13d9d5da883, 8, 2.63217811300123973067e+2L), > +sa3u =3D LD80C(0x9f8cba6d1ae1b24b, 10, 1.27639775710344617587e+3L), > +sa4u =3D LD80C(0xcaa83f403713e33e, 11, 3.24251544209971162003e+3L), > +sa5u =3D LD80C(0x8796aff2f3c47968, 12, 4.33883591261332837874e+3L), > +sa6u =3D LD80C(0xb6ef97f9c753157b, 11, 2.92697460344182158454e+3L), > +sa7u =3D LD80C(0xe02aee5f83773d1c, 9, 8.96670799139389559818e+2L), > +sa8u =3D LD80C(0xc82b83855b88e07e, 6, 1.00084987800048510018e+2L), > +sa9u =3D LD80C(0x92f030aefadf28ad, 1, 2.29591004455459083843e+0L); > +#define ra0 (ra0u.e) > +#define ra1 (ra1u.e) > +#define ra2 (ra2u.e) > +#define ra3 (ra3u.e) > +#define ra4 (ra4u.e) > +#define ra5 (ra5u.e) > +#define ra6 (ra6u.e) > +#define ra7 (ra7u.e) > +#define ra8 (ra8u.e) > +#define ra9 (ra9u.e) > +#define sa1 (sa1u.e) > +#define sa2 (sa2u.e) > +#define sa3 (sa3u.e) > +#define sa4 (sa4u.e) > +#define sa5 (sa5u.e) > +#define sa6 (sa6u.e) > +#define sa7 (sa7u.e) > +#define sa8 (sa8u.e) > +#define sa9 (sa9u.e) > +/* > + * Domain [2.85715,7], range ~[-8.323e-22,8.390e-22]: > + * |log(x*erfc(x)) + x**2 + 0.5625 - rb(x)/sb(x)| < 2**-70.326 > + */ > +static const union IEEEl2bits > +rb0u =3D LD80C(0xa1a091cf43abcd26, -7, -9.86494292470284646962e-3L), > +rb1u =3D LD80C(0xd19d2df1cbb8da0a, -1, -8.18804618389296662837e-1L), > +rb2u =3D LD80C(0x9a4dd1383e5daf5b, 4, -1.92879967111618594779e+1L), > +rb3u =3D LD80C(0xbff0ae9fc0751de6, 7, -1.91940164551245394969e+2L), > +rb4u =3D LD80C(0xdde08465310b472b, 9, -8.87508080766577324539e+2L), > +rb5u =3D LD80C(0xe796e1d38c8c70a9, 10, -1.85271506669474503781e+3L), > +rb6u =3D LD80C(0xbaf655a76e0ab3b5, 10, -1.49569795581333675349e+3L), > +rb7u =3D LD80C(0x95d21e3e75503c21, 8, -2.99641547972948019157e+2L), > +sb1u =3D LD80C(0x814487ed823c8cbd, 5, 3.23169247732868256569e+1L), > +sb2u =3D LD80C(0xbe4bfbb1301304be, 8, 3.80593618534539961773e+2L), > +sb3u =3D LD80C(0x809c4ade46b927c7, 11, 2.05776827838541292848e+3L), > +sb4u =3D LD80C(0xa55284359f3395a8, 12, 5.29031455540062116327e+3L), > +sb5u =3D LD80C(0xbcfa72da9b820874, 12, 6.04730608102312640462e+3L), > +sb6u =3D LD80C(0x9d09a35988934631, 11, 2.51260238030767176221e+3L), > +sb7u =3D LD80C(0xd675bbe542c159fa, 7, 2.14459898308561015684e+2L); > +#define rb0 (rb0u.e) > +#define rb1 (rb1u.e) > +#define rb2 (rb2u.e) > +#define rb3 (rb3u.e) > +#define rb4 (rb4u.e) > +#define rb5 (rb5u.e) > +#define rb6 (rb6u.e) > +#define rb7 (rb7u.e) > +#define sb1 (sb1u.e) > +#define sb2 (sb2u.e) > +#define sb3 (sb3u.e) > +#define sb4 (sb4u.e) > +#define sb5 (sb5u.e) > +#define sb6 (sb6u.e) > +#define sb7 (sb7u.e) > +/* > + * Domain [7,108], range ~[-4.422e-22,4.422e-22]: > + * |log(x*erfc(x)) + x**2 + 0.5625 - rc(x)/sc(x)| < 2**-70.938 > + */ > +static const union IEEEl2bits > +/* err =3D -4.422092275318925082e-22 -70.937689 */ > +rc0u =3D LD80C(0xa1a091cf437a17ad, -7, -9.86494292470008707260e-3L), > +rc1u =3D LD80C(0xbe79c5a978122b00, -1, -7.44045595049165939261e-1L), > +rc2u =3D LD80C(0xdb26f9bbe31a2794, 3, -1.36970155085888424425e+1L), > +rc3u =3D LD80C(0xb5f69a38f5747ac8, 6, -9.09816453742625888546e+1L), > +rc4u =3D LD80C(0xd79676d970d0a21a, 7, -2.15587750997584074147e+2L), > +rc5u =3D LD80C(0xfe528153c45ec97c, 6, -1.27161142938347796666e+2L), > +sc1u =3D LD80C(0xc5e8cd46d5604a96, 4, 2.47386727842204312937e+1L), > +sc2u =3D LD80C(0xc5f0f5a5484520eb, 7, 1.97941248254913378865e+2L), > +sc3u =3D LD80C(0x964e3c7b34db9170, 9, 6.01222441484087787522e+2L), > +sc4u =3D LD80C(0x99be1b89faa0596a, 9, 6.14970430845978077827e+2L), > +sc5u =3D LD80C(0xf80dfcbf37ffc5ea, 6, 1.24027318931184605891e+2L); > +#define rc0 (rc0u.e) > +#define rc1 (rc1u.e) > +#define rc2 (rc2u.e) > +#define rc3 (rc3u.e) > +#define rc4 (rc4u.e) > +#define rc5 (rc5u.e) > +#define sc1 (sc1u.e) > +#define sc2 (sc2u.e) > +#define sc3 (sc3u.e) > +#define sc4 (sc4u.e) > +#define sc5 (sc5u.e) > + > +long double > +erfl(long double x) > +{ > + long double ax,R,S,P,Q,s,y,z,r; > + uint64_t lx; > + int32_t i; > + uint16_t hx; > + > + EXTRACT_LDBL80_WORDS(hx, lx, x); > + > + if((hx & 0x7fff) =3D=3D 0x7fff) { /* erfl(nan)=3Dnan */ > + i =3D (hx>>15)<<1; > + return (1-i)+one/x; /* erfl(+-inf)=3D+-1 */ > + } > + > + ENTERI(); > + > + ax =3D fabsl(x); > + if(ax < 0.84375) { > + if(ax < 0x1p-34L) { > + if(ax < 0x1p-16373L) > + RETURNI((8*x+efx8*x)/8); /* avoid spurious underflow= */ > + RETURNI(x + efx*x); > + } > + z =3D x*x; > + r =3D pp0+z*(pp1+z*(pp2+z*(pp3+z*(pp4+z*pp5)))); > + s =3D one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*(qq5+z*qq6))))); > + y =3D r/s; > + RETURNI(x + x*y); > + } > + if(ax < 1.25) { > + s =3D ax-one; > + P =3D pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*(pa6+s*pa7))))))= ; > + Q =3D one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*(qa6+s*qa7))))))= ; > + if(x>=3D0) RETURNI(erx + P/Q); else RETURNI(-erx - P/Q); > + } > + if(ax >=3D 7) { /* inf>|x|>=3D 7 */ > + if(x>=3D0) RETURNI(one-tiny); else RETURNI(tiny-one); > + } > + s =3D one/(ax*ax); > + if(ax < 2.85715) { /* |x| < 2.85715 */ > + R=3Dra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(ra5+s*(ra6+s*(ra7+ > + s*(ra8+s*ra9)))))))); > + S=3Done+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+ > + s*(sa8+s*sa9)))))))); > + } else { /* |x| >=3D 2.85715 */ > + R=3Drb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*(rb6+s*rb7)))))); > + S=3Done+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*sb7)))))); > + } > + z=3D(float)ax; > + r=3Dexpl(-z*z-0.5625)*expl((z-ax)*(z+ax)+R/S); > + if(x>=3D0) RETURNI(one-r/ax); else RETURNI(r/ax-one); > +} > + > +long double > +erfcl(long double x) > +{ > + long double ax,R,S,P,Q,s,y,z,r; > + uint64_t lx; > + uint16_t hx; > + > + EXTRACT_LDBL80_WORDS(hx, lx, x); > + > + if((hx & 0x7fff) =3D=3D 0x7fff) { /* erfcl(nan)=3Dnan */ > + /* erfcl(+-inf)=3D0,2 */ > + return ((hx>>15)<<1)+one/x; > + } > + > + ENTERI(); > + > + ax =3D fabsl(x); > + if(ax < 0.84375L) { > + if(ax < 0x1p-34L) > + RETURNI(one-x); > + z =3D x*x; > + r =3D pp0+z*(pp1+z*(pp2+z*(pp3+z*(pp4+z*pp5)))); > + s =3D one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*(qq5+z*qq6))))); > + y =3D r/s; > + if(ax < 0.25L) { /* x<1/4 */ > + RETURNI(one-(x+x*y)); > + } else { > + r =3D x*y; > + r +=3D (x-half); > + RETURNI(half - r); > + } > + } > + if(ax < 1.25L) { > + s =3D ax-one; > + P =3D pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*(pa6+s*pa7))))))= ; > + Q =3D one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*(qa6+s*qa7))))))= ; > + if(x>=3D0) { > + z =3D one-erx; RETURNI(z - P/Q); > + } else { > + z =3D (erx+P/Q); RETURNI(one+z); > + } > + } > + > + if(ax < 108) { /* |x| < 108 */ > + s =3D one/(ax*ax); > + if(ax < 2.85715) { /* |x| < 2.85715 */ > + R=3Dra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(ra5+s*(ra6+s*(ra7+ > + s*(ra8+s*ra9)))))))); > + S=3Done+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+ > + s*(sa8+s*sa9)))))))); > + } else if(ax < 7) { /* | |x| < 7 */ > + R=3Drb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*(rb6+s*rb7))))= )); > + S=3Done+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*sb7))))= )); > + } else { > + if(x < -7) RETURNI(two-tiny);/* x < -7 */ > + R=3Drc0+s*(rc1+s*(rc2+s*(rc3+s*(rc4+s*rc5)))); > + S=3Done+s*(sc1+s*(sc2+s*(sc3+s*(sc4+s*sc5)))); > + } > + z =3D (float)ax; > + r =3D expl(-z*z-0.5625)*expl((z-ax)*(z+ax)+R/S); > + if(x>0) RETURNI(r/ax); else RETURNI(two-r/ax); > + } else { > + if(x>0) RETURNI(tiny*tiny); else RETURNI(two-tiny); > + } > +} > diff --git a/newlib/libm/ld80/s_exp2l.c b/newlib/libm/ld80/s_exp2l.c > new file mode 100644 > index 000000000..421d6e2e0 > --- /dev/null > +++ b/newlib/libm/ld80/s_exp2l.c > @@ -0,0 +1,290 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2005-2008 David Schultz > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D > + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE > + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL > + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS > + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT > + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY > + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F > + * SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +#include > +#include > + > +#ifdef __i386__ > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +#define TBLBITS 7 > +#define TBLSIZE (1 << TBLBITS) > + > +#define BIAS (LDBL_MAX_EXP - 1) > + > +static volatile long double > + huge =3D 0x1p10000L, > + twom10000 =3D 0x1p-10000L; > + > +static const union IEEEl2bits > +P1 =3D LD80C(0xb17217f7d1cf79ac, -1, 6.93147180559945309429e-1L); > + > +static const double > +redux =3D 0x1.8p63 / TBLSIZE, > +/* > + * Domain [-0.00390625, 0.00390625], range ~[-1.7079e-23, 1.7079e-23] > + * |exp(x) - p(x)| < 2**-75.6 > + */ > +P2 =3D 2.4022650695910072e-1, /* 0x1ebfbdff82c58f.0p-55 */ > +P3 =3D 5.5504108664816879e-2, /* 0x1c6b08d7049e1a.0p-57 */ > +P4 =3D 9.6181291055695180e-3, /* 0x13b2ab6fa8321a.0p-59 */ > +P5 =3D 1.3333563089183052e-3, /* 0x15d8806f67f251.0p-62 */ > +P6 =3D 1.5413361552277414e-4; /* 0x1433ddacff3441.0p-65 */ > + > +static const double tbl[TBLSIZE * 2] =3D { > + 0x1.6a09e667f3bcdp-1, -0x1.bdd3413b2648p-55, > + 0x1.6c012750bdabfp-1, -0x1.2895667ff0cp-57, > + 0x1.6dfb23c651a2fp-1, -0x1.bbe3a683c88p-58, > + 0x1.6ff7df9519484p-1, -0x1.83c0f25860fp-56, > + 0x1.71f75e8ec5f74p-1, -0x1.16e4786887bp-56, > + 0x1.73f9a48a58174p-1, -0x1.0a8d96c65d5p-55, > + 0x1.75feb564267c9p-1, -0x1.0245957316ep-55, > + 0x1.780694fde5d3fp-1, 0x1.866b80a0216p-55, > + 0x1.7a11473eb0187p-1, -0x1.41577ee0499p-56, > + 0x1.7c1ed0130c132p-1, 0x1.f124cd1164ep-55, > + 0x1.7e2f336cf4e62p-1, 0x1.05d02ba157ap-57, > + 0x1.80427543e1a12p-1, -0x1.27c86626d97p-55, > + 0x1.82589994cce13p-1, -0x1.d4c1dd41533p-55, > + 0x1.8471a4623c7adp-1, -0x1.8d684a341cep-56, > + 0x1.868d99b4492edp-1, -0x1.fc6f89bd4f68p-55, > + 0x1.88ac7d98a6699p-1, 0x1.994c2f37cb5p-55, > + 0x1.8ace5422aa0dbp-1, 0x1.6e9f156864bp-55, > + 0x1.8cf3216b5448cp-1, -0x1.0d55e32e9e4p-57, > + 0x1.8f1ae99157736p-1, 0x1.5cc13a2e397p-56, > + 0x1.9145b0b91ffc6p-1, -0x1.dd6792e5825p-55, > + 0x1.93737b0cdc5e5p-1, -0x1.75fc781b58p-58, > + 0x1.95a44cbc8520fp-1, -0x1.64b7c96a5fp-57, > + 0x1.97d829fde4e5p-1, -0x1.d185b7c1b86p-55, > + 0x1.9a0f170ca07bap-1, -0x1.173bd91cee6p-55, > + 0x1.9c49182a3f09p-1, 0x1.c7c46b071f2p-57, > + 0x1.9e86319e32323p-1, 0x1.824ca78e64cp-57, > + 0x1.a0c667b5de565p-1, -0x1.359495d1cd5p-55, > + 0x1.a309bec4a2d33p-1, 0x1.6305c7ddc368p-55, > + 0x1.a5503b23e255dp-1, -0x1.d2f6edb8d42p-55, > + 0x1.a799e1330b358p-1, 0x1.bcb7ecac564p-55, > + 0x1.a9e6b5579fdbfp-1, 0x1.0fac90ef7fdp-55, > + 0x1.ac36bbfd3f37ap-1, -0x1.f9234cae76dp-56, > + 0x1.ae89f995ad3adp-1, 0x1.7a1cd345dcc8p-55, > + 0x1.b0e07298db666p-1, -0x1.bdef54c80e4p-55, > + 0x1.b33a2b84f15fbp-1, -0x1.2805e3084d8p-58, > + 0x1.b59728de5593ap-1, -0x1.c71dfbbba6ep-55, > + 0x1.b7f76f2fb5e47p-1, -0x1.5584f7e54acp-57, > + 0x1.ba5b030a1064ap-1, -0x1.efcd30e5429p-55, > + 0x1.bcc1e904bc1d2p-1, 0x1.23dd07a2d9fp-56, > + 0x1.bf2c25bd71e09p-1, -0x1.efdca3f6b9c8p-55, > + 0x1.c199bdd85529cp-1, 0x1.11065895049p-56, > + 0x1.c40ab5fffd07ap-1, 0x1.b4537e083c6p-55, > + 0x1.c67f12e57d14bp-1, 0x1.2884dff483c8p-55, > + 0x1.c8f6d9406e7b5p-1, 0x1.1acbc48805cp-57, > + 0x1.cb720dcef9069p-1, 0x1.503cbd1e94ap-57, > + 0x1.cdf0b555dc3fap-1, -0x1.dd83b53829dp-56, > + 0x1.d072d4a07897cp-1, -0x1.cbc3743797a8p-55, > + 0x1.d2f87080d89f2p-1, -0x1.d487b719d858p-55, > + 0x1.d5818dcfba487p-1, 0x1.2ed02d75b37p-56, > + 0x1.d80e316c98398p-1, -0x1.11ec18bedep-55, > + 0x1.da9e603db3285p-1, 0x1.c2300696db5p-55, > + 0x1.dd321f301b46p-1, 0x1.2da5778f019p-55, > + 0x1.dfc97337b9b5fp-1, -0x1.1a5cd4f184b8p-55, > + 0x1.e264614f5a129p-1, -0x1.7b627817a148p-55, > + 0x1.e502ee78b3ff6p-1, 0x1.39e8980a9cdp-56, > + 0x1.e7a51fbc74c83p-1, 0x1.2d522ca0c8ep-55, > + 0x1.ea4afa2a490dap-1, -0x1.e9c23179c288p-55, > + 0x1.ecf482d8e67f1p-1, -0x1.c93f3b411ad8p-55, > + 0x1.efa1bee615a27p-1, 0x1.dc7f486a4b68p-55, > + 0x1.f252b376bba97p-1, 0x1.3a1a5bf0d8e8p-55, > + 0x1.f50765b6e454p-1, 0x1.9d3e12dd8a18p-55, > + 0x1.f7bfdad9cbe14p-1, -0x1.dbb12d00635p-55, > + 0x1.fa7c1819e90d8p-1, 0x1.74853f3a593p-56, > + 0x1.fd3c22b8f71f1p-1, 0x1.2eb74966578p-58, > + 0x1p+0, 0x0p+0, > + 0x1.0163da9fb3335p+0, 0x1.b61299ab8cd8p-54, > + 0x1.02c9a3e778061p+0, -0x1.19083535b08p-56, > + 0x1.04315e86e7f85p+0, -0x1.0a31c1977c98p-54, > + 0x1.059b0d3158574p+0, 0x1.d73e2a475b4p-55, > + 0x1.0706b29ddf6dep+0, -0x1.c91dfe2b13cp-55, > + 0x1.0874518759bc8p+0, 0x1.186be4bb284p-57, > + 0x1.09e3ecac6f383p+0, 0x1.14878183161p-54, > + 0x1.0b5586cf9890fp+0, 0x1.8a62e4adc61p-54, > + 0x1.0cc922b7247f7p+0, 0x1.01edc16e24f8p-54, > + 0x1.0e3ec32d3d1a2p+0, 0x1.03a1727c58p-59, > + 0x1.0fb66affed31bp+0, -0x1.b9bedc44ebcp-57, > + 0x1.11301d0125b51p+0, -0x1.6c51039449bp-54, > + 0x1.12abdc06c31ccp+0, -0x1.1b514b36ca8p-58, > + 0x1.1429aaea92dep+0, -0x1.32fbf9af1368p-54, > + 0x1.15a98c8a58e51p+0, 0x1.2406ab9eeabp-55, > + 0x1.172b83c7d517bp+0, -0x1.19041b9d78ap-55, > + 0x1.18af9388c8deap+0, -0x1.11023d1970f8p-54, > + 0x1.1a35beb6fcb75p+0, 0x1.e5b4c7b4969p-55, > + 0x1.1bbe084045cd4p+0, -0x1.95386352ef6p-54, > + 0x1.1d4873168b9aap+0, 0x1.e016e00a264p-54, > + 0x1.1ed5022fcd91dp+0, -0x1.1df98027bb78p-54, > + 0x1.2063b88628cd6p+0, 0x1.dc775814a85p-55, > + 0x1.21f49917ddc96p+0, 0x1.2a97e9494a6p-55, > + 0x1.2387a6e756238p+0, 0x1.9b07eb6c7058p-54, > + 0x1.251ce4fb2a63fp+0, 0x1.ac155bef4f5p-55, > + 0x1.26b4565e27cddp+0, 0x1.2bd339940eap-55, > + 0x1.284dfe1f56381p+0, -0x1.a4c3a8c3f0d8p-54, > + 0x1.29e9df51fdee1p+0, 0x1.612e8afad12p-55, > + 0x1.2b87fd0dad99p+0, -0x1.10adcd6382p-59, > + 0x1.2d285a6e4030bp+0, 0x1.0024754db42p-54, > + 0x1.2ecafa93e2f56p+0, 0x1.1ca0f45d524p-56, > + 0x1.306fe0a31b715p+0, 0x1.6f46ad23183p-55, > + 0x1.32170fc4cd831p+0, 0x1.a9ce78e1804p-55, > + 0x1.33c08b26416ffp+0, 0x1.327218436598p-54, > + 0x1.356c55f929ff1p+0, -0x1.b5cee5c4e46p-55, > + 0x1.371a7373aa9cbp+0, -0x1.63aeabf42ebp-54, > + 0x1.38cae6d05d866p+0, -0x1.e958d3c99048p-54, > + 0x1.3a7db34e59ff7p+0, -0x1.5e436d661f6p-56, > + 0x1.3c32dc313a8e5p+0, -0x1.efff8375d2ap-54, > + 0x1.3dea64c123422p+0, 0x1.ada0911f09fp-55, > + 0x1.3fa4504ac801cp+0, -0x1.7d023f956fap-54, > + 0x1.4160a21f72e2ap+0, -0x1.ef3691c309p-58, > + 0x1.431f5d950a897p+0, -0x1.1c7dde35f7ap-55, > + 0x1.44e086061892dp+0, 0x1.89b7a04ef8p-59, > + 0x1.46a41ed1d0057p+0, 0x1.c944bd1648a8p-54, > + 0x1.486a2b5c13cdp+0, 0x1.3c1a3b69062p-56, > + 0x1.4a32af0d7d3dep+0, 0x1.9cb62f3d1be8p-54, > + 0x1.4bfdad5362a27p+0, 0x1.d4397afec42p-56, > + 0x1.4dcb299fddd0dp+0, 0x1.8ecdbbc6a78p-54, > + 0x1.4f9b2769d2ca7p+0, -0x1.4b309d25958p-54, > + 0x1.516daa2cf6642p+0, -0x1.f768569bd94p-55, > + 0x1.5342b569d4f82p+0, -0x1.07abe1db13dp-55, > + 0x1.551a4ca5d920fp+0, -0x1.d689cefede6p-55, > + 0x1.56f4736b527dap+0, 0x1.9bb2c011d938p-54, > + 0x1.58d12d497c7fdp+0, 0x1.295e15b9a1ep-55, > + 0x1.5ab07dd485429p+0, 0x1.6324c0546478p-54, > + 0x1.5c9268a5946b7p+0, 0x1.c4b1b81698p-60, > + 0x1.5e76f15ad2148p+0, 0x1.ba6f93080e68p-54, > + 0x1.605e1b976dc09p+0, -0x1.3e2429b56de8p-54, > + 0x1.6247eb03a5585p+0, -0x1.383c17e40b48p-54, > + 0x1.6434634ccc32p+0, -0x1.c483c759d89p-55, > + 0x1.6623882552225p+0, -0x1.bb60987591cp-54, > + 0x1.68155d44ca973p+0, 0x1.038ae44f74p-57, > +}; > + > +/** > + * Compute the base 2 exponential of x for Intel 80-bit format. > + * > + * Accuracy: Peak error < 0.511 ulp. > + * > + * Method: (equally-spaced tables) > + * > + * Reduce x: > + * x =3D 2**k + y, for integer k and |y| <=3D 1/2. > + * Thus we have exp2l(x) =3D 2**k * exp2(y). > + * > + * Reduce y: > + * y =3D i/TBLSIZE + z for integer i near y * TBLSIZE. > + * Thus we have exp2(y) =3D exp2(i/TBLSIZE) * exp2(z), > + * with |z| <=3D 2**-(TBLBITS+1). > + * > + * We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a > + * degree-6 minimax polynomial with maximum error under 2**-75.6. > + * The table entries each have 104 bits of accuracy, encoded as > + * a pair of double precision values. > + */ > +long double > +exp2l(long double x) > +{ > + union IEEEl2bits u, v; > + long double r, twopk, twopkp10000, z; > + uint32_t hx, ix, i0; > + int k; > + > + /* Filter out exceptional cases. */ > + u.e =3D x; > + hx =3D u.xbits.expsign; > + ix =3D hx & 0x7fff; > + if (ix >=3D BIAS + 14) { /* |x| >=3D 16384 or x is NaN */ > + if (ix =3D=3D BIAS + LDBL_MAX_EXP) { > + if (hx & 0x8000 && u.xbits.man =3D=3D 1ULL << 63) > + return (0.0L); /* x is -Inf */ > + return (x + x); /* x is +Inf, NaN or unsupported */ > + } > + if (x >=3D 16384) > + return (huge * huge); /* overflow */ > + if (x <=3D -16446) > + return (twom10000 * twom10000); /* underflow */ > + } else if (ix <=3D BIAS - 66) { /* |x| < 0x1p-65 (includes pseudo= s) */ > + return (1.0L + x); /* 1 with inexact */ > + } > + > + ENTERI(); > + > + /* > + * Reduce x, computing z, i0, and k. The low bits of x + redux > + * contain the 16-bit integer part of the exponent (k) followed by > + * TBLBITS fractional bits (i0). We use bit tricks to extract these > + * as integers, then set z to the remainder. > + * > + * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8. > + * Then the low-order word of x + redux is 0x000abc12, > + * We split this into k =3D 0xabc and i0 =3D 0x12 (adjusted to > + * index into the table), then we compute z =3D 0x0.003456p0. > + * > + * XXX If the exponent is negative, the computation of k depends on > + * '>>' doing sign extension. > + */ > + u.e =3D x + redux; > + i0 =3D u.bits.manl + TBLSIZE / 2; > + k =3D (int)i0 >> TBLBITS; > + i0 =3D (i0 & (TBLSIZE - 1)) << 1; > + u.e -=3D redux; > + z =3D x - u.e; > + v.xbits.man =3D 1ULL << 63; > + if (k >=3D LDBL_MIN_EXP) { > + v.xbits.expsign =3D BIAS + k; > + twopk =3D v.e; > + } else { > + v.xbits.expsign =3D BIAS + k + 10000; > + twopkp10000 =3D v.e; > + } > + > + /* Compute r =3D exp2l(y) =3D exp2lt[i0] * p(z). */ > + long double t_hi =3D tbl[i0]; > + long double t_lo =3D tbl[i0 + 1]; > + r =3D t_lo + (t_hi + t_lo) * z * (P1.e + z * (P2 + z * (P3 + z * (P= 4 > + + z * (P5 + z * P6))))) + t_hi; > + > + /* Scale by 2**k. */ > + if (k >=3D LDBL_MIN_EXP) { > + if (k =3D=3D LDBL_MAX_EXP) > + RETURNI(r * 2.0 * 0x1p16383L); > + RETURNI(r * twopk); > + } else { > + RETURNI(r * twopkp10000 * twom10000); > + } > +} > diff --git a/newlib/libm/ld80/s_expl.c b/newlib/libm/ld80/s_expl.c > new file mode 100644 > index 000000000..e46e73f0c > --- /dev/null > +++ b/newlib/libm/ld80/s_expl.c > @@ -0,0 +1,279 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2009-2013 Steven G. Kargl > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice unmodified, this list of conditions, and the following > + * disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + * > + * Optimized by Bruce D. Evans. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/** > + * Compute the exponential of x for Intel 80-bit format. This is based = on: > + * > + * PTP Tang, "Table-driven implementation of the exponential function > + * in IEEE floating-point arithmetic," ACM Trans. Math. Soft., 15, > + * 144-157 (1989). > + * > + * where the 32 table entries have been expanded to INTERVALS (see below= ). > + */ > + > +#include > + > +#ifdef __i386__ > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > +#include "k_expl.h" > + > +/* XXX Prevent compilers from erroneously constant folding these: */ > +static const volatile long double > +huge =3D 0x1p10000L, > +tiny =3D 0x1p-10000L; > + > +static const long double > +twom10000 =3D 0x1p-10000L; > + > +static const union IEEEl2bits > +/* log(2**16384 - 0.5) rounded towards zero: */ > +/* log(2**16384 - 0.5 + 1) rounded towards zero for expm1l() is the same= : */ > +o_thresholdu =3D LD80C(0xb17217f7d1cf79ab, 13, 11356.5234062941439488L)= , > +#define o_threshold (o_thresholdu.e) > +/* log(2**(-16381-64-1)) rounded towards zero: */ > +u_thresholdu =3D LD80C(0xb21dfe7f09e2baa9, 13, -11399.4985314888605581L)= ; > +#define u_threshold (u_thresholdu.e) > + > +long double > +expl(long double x) > +{ > + union IEEEl2bits u; > + long double hi, lo, t, twopk; > + int k; > + uint16_t hx, ix; > + > + DOPRINT_START(&x); > + > + /* Filter out exceptional cases. */ > + u.e =3D x; > + hx =3D u.xbits.expsign; > + ix =3D hx & 0x7fff; > + if (ix >=3D BIAS + 13) { /* |x| >=3D 8192 or x is NaN */ > + if (ix =3D=3D BIAS + LDBL_MAX_EXP) { > + if (hx & 0x8000) /* x is -Inf, -NaN or unsupported= */ > + RETURNP(-1 / x); > + RETURNP(x + x); /* x is +Inf, +NaN or unsupported *= / > + } > + if (x > o_threshold) > + RETURNP(huge * huge); > + if (x < u_threshold) > + RETURNP(tiny * tiny); > + } else if (ix < BIAS - 75) { /* |x| < 0x1p-75 (includes pseudos)= */ > + RETURN2P(1, x); /* 1 with inexact iff x !=3D 0 */ > + } > + > + ENTERI(); > + > + twopk =3D 1; > + __k_expl(x, &hi, &lo, &k); > + t =3D SUM2P(hi, lo); > + > + /* Scale by 2**k. */ > + if (k >=3D LDBL_MIN_EXP) { > + if (k =3D=3D LDBL_MAX_EXP) > + RETURNI(t * 2 * 0x1p16383L); > + SET_LDBL_EXPSIGN(twopk, BIAS + k); > + RETURNI(t * twopk); > + } else { > + SET_LDBL_EXPSIGN(twopk, BIAS + k + 10000); > + RETURNI(t * twopk * twom10000); > + } > +} > + > +/** > + * Compute expm1l(x) for Intel 80-bit format. This is based on: > + * > + * PTP Tang, "Table-driven implementation of the Expm1 function > + * in IEEE floating-point arithmetic," ACM Trans. Math. Soft., 18, > + * 211-222 (1992). > + */ > + > +/* > + * Our T1 and T2 are chosen to be approximately the points where method > + * A and method B have the same accuracy. Tang's T1 and T2 are the > + * points where method A's accuracy changes by a full bit. For Tang, > + * this drop in accuracy makes method A immediately less accurate than > + * method B, but our larger INTERVALS makes method A 2 bits more > + * accurate so it remains the most accurate method significantly > + * closer to the origin despite losing the full bit in our extended > + * range for it. > + */ > +static const double > +T1 =3D -0.1659, /* ~-30.625/128 * log(2) = */ > +T2 =3D 0.1659; /* ~30.625/128 * log(2) *= / > + > +/* > + * Domain [-0.1659, 0.1659], range ~[-2.6155e-22, 2.5507e-23]: > + * |(exp(x)-1-x-x**2/2)/x - p(x)| < 2**-71.6 > + * > + * XXX the coeffs aren't very carefully rounded, and I get 2.8 more bits= , > + * but unlike for ld128 we can't drop any terms. > + */ > +static const union IEEEl2bits > +B3 =3D LD80C(0xaaaaaaaaaaaaaaab, -3, 1.66666666666666666671e-1L), > +B4 =3D LD80C(0xaaaaaaaaaaaaaaac, -5, 4.16666666666666666712e-2L); > + > +static const double > +B5 =3D 8.3333333333333245e-3, /* 0x1.111111111110cp-7 = */ > +B6 =3D 1.3888888888888861e-3, /* 0x1.6c16c16c16c0ap-10= */ > +B7 =3D 1.9841269841532042e-4, /* 0x1.a01a01a0319f9p-13= */ > +B8 =3D 2.4801587302069236e-5, /* 0x1.a01a01a03cbbcp-16= */ > +B9 =3D 2.7557316558468562e-6, /* 0x1.71de37fd33d67p-19= */ > +B10 =3D 2.7557315829785151e-7, /* 0x1.27e4f91418144p-22= */ > +B11 =3D 2.5063168199779829e-8, /* 0x1.ae94fabdc6b27p-26= */ > +B12 =3D 2.0887164654459567e-9; /* 0x1.1f122d6413fe1p-29= */ > + > +long double > +expm1l(long double x) > +{ > + union IEEEl2bits u, v; > + long double fn, hx2_hi, hx2_lo, q, r, r1, r2, t, twomk, twopk, x_hi= ; > + long double x_lo, x2, z; > + long double x4; > + int k, n, n2; > + uint16_t hx, ix; > + > + DOPRINT_START(&x); > + > + /* Filter out exceptional cases. */ > + u.e =3D x; > + hx =3D u.xbits.expsign; > + ix =3D hx & 0x7fff; > + if (ix >=3D BIAS + 6) { /* |x| >=3D 64 or x is NaN */ > + if (ix =3D=3D BIAS + LDBL_MAX_EXP) { > + if (hx & 0x8000) /* x is -Inf, -NaN or unsupported= */ > + RETURNP(-1 / x - 1); > + RETURNP(x + x); /* x is +Inf, +NaN or unsupported *= / > + } > + if (x > o_threshold) > + RETURNP(huge * huge); > + /* > + * expm1l() never underflows, but it must avoid > + * unrepresentable large negative exponents. We used a > + * much smaller threshold for large |x| above than in > + * expl() so as to handle not so large negative exponents > + * in the same way as large ones here. > + */ > + if (hx & 0x8000) /* x <=3D -64 */ > + RETURN2P(tiny, -1); /* good for x < -65ln2 - ep= s */ > + } > + > + ENTERI(); > + > + if (T1 < x && x < T2) { > + if (ix < BIAS - 74) { /* |x| < 0x1p-74 (includes pseudos)= */ > + /* x (rounded) with inexact if x !=3D 0: */ > + RETURNPI(x =3D=3D 0 ? x : > + (0x1p100 * x + fabsl(x)) * 0x1p-100); > + } > + > + x2 =3D x * x; > + x4 =3D x2 * x2; > + q =3D x4 * (x2 * (x4 * > + /* > + * XXX the number of terms is no longer good for > + * pairwise grouping of all except B3, and the > + * grouping is no longer from highest down. > + */ > + (x2 * B12 + (x * B11 + B10)) + > + (x2 * (x * B9 + B8) + (x * B7 + B6))) + > + (x * B5 + B4.e)) + x2 * x * B3.e; > + > + x_hi =3D (float)x; > + x_lo =3D x - x_hi; > + hx2_hi =3D x_hi * x_hi / 2; > + hx2_lo =3D x_lo * (x + x_hi) / 2; > + if (ix >=3D BIAS - 7) > + RETURN2PI(hx2_hi + x_hi, hx2_lo + x_lo + q); > + else > + RETURN2PI(x, hx2_lo + q + hx2_hi); > + } > + > + /* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */ > + fn =3D rnintl(x * INV_L); > + n =3D irint(fn); > + n2 =3D (unsigned)n % INTERVALS; > + k =3D n >> LOG2_INTERVALS; > + r1 =3D x - fn * L1; > + r2 =3D fn * -L2; > + r =3D r1 + r2; > + > + /* Prepare scale factor. */ > + v.e =3D 1; > + v.xbits.expsign =3D BIAS + k; > + twopk =3D v.e; > + > + /* > + * Evaluate lower terms of > + * expl(endpoint[n2] + r1 + r2) =3D tbl[n2] * expl(r1 + r2). > + */ > + z =3D r * r; > + q =3D r2 + z * (A2 + r * A3) + z * z * (A4 + r * A5) + z * z * z * = A6; > + > + t =3D (long double)tbl[n2].lo + tbl[n2].hi; > + > + if (k =3D=3D 0) { > + t =3D SUM2P(tbl[n2].hi - 1, tbl[n2].lo * (r1 + 1) + t * q + > + tbl[n2].hi * r1); > + RETURNI(t); > + } > + if (k =3D=3D -1) { > + t =3D SUM2P(tbl[n2].hi - 2, tbl[n2].lo * (r1 + 1) + t * q + > + tbl[n2].hi * r1); > + RETURNI(t / 2); > + } > + if (k < -7) { > + t =3D SUM2P(tbl[n2].hi, tbl[n2].lo + t * (q + r1)); > + RETURNI(t * twopk - 1); > + } > + if (k > 2 * LDBL_MANT_DIG - 1) { > + t =3D SUM2P(tbl[n2].hi, tbl[n2].lo + t * (q + r1)); > + if (k =3D=3D LDBL_MAX_EXP) > + RETURNI(t * 2 * 0x1p16383L - 1); > + RETURNI(t * twopk - 1); > + } > + > + v.xbits.expsign =3D BIAS - k; > + twomk =3D v.e; > + > + if (k > LDBL_MANT_DIG - 1) > + t =3D SUM2P(tbl[n2].hi, tbl[n2].lo - twomk + t * (q + r1)); > + else > + t =3D SUM2P(tbl[n2].hi - twomk, tbl[n2].lo + t * (q + r1)); > + RETURNI(t * twopk); > +} > diff --git a/newlib/libm/ld80/s_logl.c b/newlib/libm/ld80/s_logl.c > new file mode 100644 > index 000000000..c74519caf > --- /dev/null > +++ b/newlib/libm/ld80/s_logl.c > @@ -0,0 +1,722 @@ > +/*- > + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD > + * > + * Copyright (c) 2007-2013 Bruce D. Evans > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice unmodified, this list of conditions, and the following > + * disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include > +__FBSDID("$FreeBSD$"); > + > +/** > + * Implementation of the natural logarithm of x for Intel 80-bit format. > + * > + * First decompose x into its base 2 representation: > + * > + * log(x) =3D log(X * 2**k), where X is in [1, 2) > + * =3D log(X) + k * log(2). > + * > + * Let X =3D X_i + e, where X_i is the center of one of the intervals > + * [-1.0/256, 1.0/256), [1.0/256, 3.0/256), .... [2.0-1.0/256, 2.0+1.0/2= 56) > + * and X is in this interval. Then > + * > + * log(X) =3D log(X_i + e) > + * =3D log(X_i * (1 + e / X_i)) > + * =3D log(X_i) + log(1 + e / X_i). > + * > + * The values log(X_i) are tabulated below. Let d =3D e / X_i and use > + * > + * log(1 + d) =3D p(d) > + * > + * where p(d) =3D d - 0.5*d*d + ... is a special minimax polynomial of > + * suitably high degree. > + * > + * To get sufficiently small roundoff errors, k * log(2), log(X_i), and > + * sometimes (if |k| is not large) the first term in p(d) must be evalua= ted > + * and added up in extra precision. Extra precision is not needed for t= he > + * rest of p(d). In the worst case when k =3D 0 and log(X_i) is 0, the = final > + * error is controlled mainly by the error in the second term in p(d). = The > + * error in this term itself is at most 0.5 ulps from the d*d operation = in > + * it. The error in this term relative to the first term is thus at mos= t > + * 0.5 * |-0.5| * |d| < 1.0/1024 ulps. We aim for an accumulated error = of > + * at most twice this at the point of the final rounding step. Thus the > + * final error should be at most 0.5 + 1.0/512 =3D 0.5020 ulps. Exhaust= ive > + * testing of a float variant of this function showed a maximum final er= ror > + * of 0.5008 ulps. Non-exhaustive testing of a double variant of this > + * function showed a maximum final error of 0.5078 ulps (near 1+1.0/256)= . > + * > + * We made the maximum of |d| (and thus the total relative error and the > + * degree of p(d)) small by using a large number of intervals. Using > + * centers of intervals instead of endpoints reduces this maximum by a > + * factor of 2 for a given number of intervals. p(d) is special only > + * in beginning with the Taylor coefficients 0 + 1*d, which tends to hap= pen > + * naturally. The most accurate minimax polynomial of a given degree mi= ght > + * be different, but then we wouldn't want it since we would have to do > + * extra work to avoid roundoff error (especially for P0*d instead of d)= . > + */ > + > +#ifdef DEBUG > +#include > +#include > +#endif > + > +#ifdef __i386__ > +#include > +#endif > + > +#include "fpmath.h" > +#include "math.h" > +#define i386_SSE_GOOD > +#ifndef NO_STRUCT_RETURN > +#define STRUCT_RETURN > +#endif > +#include "math_private.h" > + > +#if !defined(NO_UTAB) && !defined(NO_UTABL) > +#define USE_UTAB > +#endif > + > +/* > + * Domain [-0.005280, 0.004838], range ~[-5.1736e-22, 5.1738e-22]: > + * |log(1 + d)/d - p(d)| < 2**-70.7 > + */ > +static const double > +P2 =3D -0.5, > +P3 =3D 3.3333333333333359e-1, /* 0x1555555555555a.0p-54 */ > +P4 =3D -2.5000000000004424e-1, /* -0x1000000000031d.0p-54 */ > +P5 =3D 1.9999999992970016e-1, /* 0x1999999972f3c7.0p-55 */ > +P6 =3D -1.6666666072191585e-1, /* -0x15555548912c09.0p-55 */ > +P7 =3D 1.4286227413310518e-1, /* 0x12494f9d9def91.0p-55 */ > +P8 =3D -1.2518388626763144e-1; /* -0x1006068cc0b97c.0p-55 */ > + > +static volatile const double zero =3D 0; > + > +#define INTERVALS 128 > +#define LOG2_INTERVALS 7 > +#define TSIZE (INTERVALS + 1) > +#define G(i) (T[(i)].G) > +#define F_hi(i) (T[(i)].F_hi) > +#define F_lo(i) (T[(i)].F_lo) > +#define ln2_hi F_hi(TSIZE - 1) > +#define ln2_lo F_lo(TSIZE - 1) > +#define E(i) (U[(i)].E) > +#define H(i) (U[(i)].H) > + > +static const struct { > + float G; /* 1/(1 + i/128) rounded to 8/9 bit= s */ > + float F_hi; /* log(1 / G_i) rounded (see below)= */ > + double F_lo; /* next 53 bits for log(1 / G_i) */ > +} T[TSIZE] =3D { > + /* > + * ln2_hi and each F_hi(i) are rounded to a number of bits that > + * makes F_hi(i) + dk*ln2_hi exact for all i and all dk. > + * > + * The last entry (for X just below 2) is used to define ln2_hi > + * and ln2_lo, to ensure that F_hi(i) and F_lo(i) cancel exactly > + * with dk*ln2_hi and dk*ln2_lo, respectively, when dk =3D -1. > + * This is needed for accuracy when x is just below 1. (To avoid > + * special cases, such x are "reduced" strangely to X just below > + * 2 and dk =3D -1, and then the exact cancellation is needed > + * because any the error from any non-exactness would be too > + * large). > + * > + * We want to share this table between double precision and ld80, > + * so the relevant range of dk is the larger one of ld80 > + * ([-16445, 16383]) and the relevant exactness requirement is > + * the stricter one of double precision. The maximum number of > + * bits in F_hi(i) that works is very dependent on i but has > + * a minimum of 33. We only need about 12 bits in F_hi(i) for > + * it to provide enough extra precision in double precision (11 > + * more than that are required for ld80). > + * > + * We round F_hi(i) to 24 bits so that it can have type float, > + * mainly to minimize the size of the table. Using all 24 bits > + * in a float for it automatically satisfies the above constraints. > + */ > + { 0x800000.0p-23, 0, 0 }, > + { 0xfe0000.0p-24, 0x8080ac.0p-30, -0x14ee431dae6675.0p-84 }, > + { 0xfc0000.0p-24, 0x8102b3.0p-29, -0x1db29ee2d83718.0p-84 }, > + { 0xfa0000.0p-24, 0xc24929.0p-29, 0x1191957d173698.0p-83 }, > + { 0xf80000.0p-24, 0x820aec.0p-28, 0x13ce8888e02e79.0p-82 }, > + { 0xf60000.0p-24, 0xa33577.0p-28, -0x17a4382ce6eb7c.0p-82 }, > + { 0xf48000.0p-24, 0xbc42cb.0p-28, -0x172a21161a1076.0p-83 }, > + { 0xf30000.0p-24, 0xd57797.0p-28, -0x1e09de07cb9589.0p-82 }, > + { 0xf10000.0p-24, 0xf7518e.0p-28, 0x1ae1eec1b036c5.0p-91 }, > + { 0xef0000.0p-24, 0x8cb9df.0p-27, -0x1d7355325d560e.0p-81 }, > + { 0xed8000.0p-24, 0x999ec0.0p-27, -0x1f9f02d256d503.0p-82 }, > + { 0xec0000.0p-24, 0xa6988b.0p-27, -0x16fc0a9d12c17a.0p-83 }, > + { 0xea0000.0p-24, 0xb80698.0p-27, 0x15d581c1e8da9a.0p-81 }, > + { 0xe80000.0p-24, 0xc99af3.0p-27, -0x1535b3ba8f150b.0p-83 }, > + { 0xe70000.0p-24, 0xd273b2.0p-27, 0x163786f5251af0.0p-85 }, > + { 0xe50000.0p-24, 0xe442c0.0p-27, 0x1bc4b2368e32d5.0p-84 }, > + { 0xe38000.0p-24, 0xf1b83f.0p-27, 0x1c6090f684e676.0p-81 }, > + { 0xe20000.0p-24, 0xff448a.0p-27, -0x1890aa69ac9f42.0p-82 }, > + { 0xe08000.0p-24, 0x8673f6.0p-26, 0x1b9985194b6b00.0p-80 }, > + { 0xdf0000.0p-24, 0x8d515c.0p-26, -0x1dc08d61c6ef1e.0p-83 }, > + { 0xdd8000.0p-24, 0x943a9e.0p-26, -0x1f72a2dac729b4.0p-82 }, > + { 0xdc0000.0p-24, 0x9b2fe6.0p-26, -0x1fd4dfd3a0afb9.0p-80 }, > + { 0xda8000.0p-24, 0xa2315d.0p-26, -0x11b26121629c47.0p-82 }, > + { 0xd90000.0p-24, 0xa93f2f.0p-26, 0x1286d633e8e569.0p-81 }, > + { 0xd78000.0p-24, 0xb05988.0p-26, 0x16128eba936770.0p-84 }, > + { 0xd60000.0p-24, 0xb78094.0p-26, 0x16ead577390d32.0p-80 }, > + { 0xd50000.0p-24, 0xbc4c6c.0p-26, 0x151131ccf7c7b7.0p-81 }, > + { 0xd38000.0p-24, 0xc3890a.0p-26, -0x115e2cd714bd06.0p-80 }, > + { 0xd20000.0p-24, 0xcad2d7.0p-26, -0x1847f406ebd3b0.0p-82 }, > + { 0xd10000.0p-24, 0xcfb620.0p-26, 0x1c2259904d6866.0p-81 }, > + { 0xcf8000.0p-24, 0xd71653.0p-26, 0x1ece57a8d5ae55.0p-80 }, > + { 0xce0000.0p-24, 0xde843a.0p-26, -0x1f109d4bc45954.0p-81 }, > + { 0xcd0000.0p-24, 0xe37fde.0p-26, 0x1bc03dc271a74d.0p-81 }, > + { 0xcb8000.0p-24, 0xeb050c.0p-26, -0x1bf2badc0df842.0p-85 }, > + { 0xca0000.0p-24, 0xf29878.0p-26, -0x18efededd89fbe.0p-87 }, > + { 0xc90000.0p-24, 0xf7ad6f.0p-26, 0x1373ff977baa69.0p-81 }, > + { 0xc80000.0p-24, 0xfcc8e3.0p-26, 0x196766f2fb3283.0p-80 }, > + { 0xc68000.0p-24, 0x823f30.0p-25, 0x19bd076f7c434e.0p-79 }, > + { 0xc58000.0p-24, 0x84d52c.0p-25, -0x1a327257af0f46.0p-79 }, > + { 0xc40000.0p-24, 0x88bc74.0p-25, 0x113f23def19c5a.0p-81 }, > + { 0xc30000.0p-24, 0x8b5ae6.0p-25, 0x1759f6e6b37de9.0p-79 }, > + { 0xc20000.0p-24, 0x8dfccb.0p-25, 0x1ad35ca6ed5148.0p-81 }, > + { 0xc10000.0p-24, 0x90a22b.0p-25, 0x1a1d71a87deba4.0p-79 }, > + { 0xbf8000.0p-24, 0x94a0d8.0p-25, -0x139e5210c2b731.0p-80 }, > + { 0xbe8000.0p-24, 0x974f16.0p-25, -0x18f6ebcff3ed73.0p-81 }, > + { 0xbd8000.0p-24, 0x9a00f1.0p-25, -0x1aa268be39aab7.0p-79 }, > + { 0xbc8000.0p-24, 0x9cb672.0p-25, -0x14c8815839c566.0p-79 }, > + { 0xbb0000.0p-24, 0xa0cda1.0p-25, 0x1eaf46390dbb24.0p-81 }, > + { 0xba0000.0p-24, 0xa38c6e.0p-25, 0x138e20d831f698.0p-81 }, > + { 0xb90000.0p-24, 0xa64f05.0p-25, -0x1e8d3c41123616.0p-82 }, > + { 0xb80000.0p-24, 0xa91570.0p-25, 0x1ce28f5f3840b2.0p-80 }, > + { 0xb70000.0p-24, 0xabdfbb.0p-25, -0x186e5c0a424234.0p-79 }, > + { 0xb60000.0p-24, 0xaeadef.0p-25, -0x14d41a0b2a08a4.0p-83 }, > + { 0xb50000.0p-24, 0xb18018.0p-25, 0x16755892770634.0p-79 }, > + { 0xb40000.0p-24, 0xb45642.0p-25, -0x16395ebe59b152.0p-82 }, > + { 0xb30000.0p-24, 0xb73077.0p-25, 0x1abc65c8595f09.0p-80 }, > + { 0xb20000.0p-24, 0xba0ec4.0p-25, -0x1273089d3dad89.0p-79 }, > + { 0xb10000.0p-24, 0xbcf133.0p-25, 0x10f9f67b1f4bbf.0p-79 }, > + { 0xb00000.0p-24, 0xbfd7d2.0p-25, -0x109fab90486409.0p-80 }, > + { 0xaf0000.0p-24, 0xc2c2ac.0p-25, -0x1124680aa43333.0p-79 }, > + { 0xae8000.0p-24, 0xc439b3.0p-25, -0x1f360cc4710fc0.0p-80 }, > + { 0xad8000.0p-24, 0xc72afd.0p-25, -0x132d91f21d89c9.0p-80 }, > + { 0xac8000.0p-24, 0xca20a2.0p-25, -0x16bf9b4d1f8da8.0p-79 }, > + { 0xab8000.0p-24, 0xcd1aae.0p-25, 0x19deb5ce6a6a87.0p-81 }, > + { 0xaa8000.0p-24, 0xd0192f.0p-25, 0x1a29fb48f7d3cb.0p-79 }, > + { 0xaa0000.0p-24, 0xd19a20.0p-25, 0x1127d3c6457f9d.0p-81 }, > + { 0xa90000.0p-24, 0xd49f6a.0p-25, -0x1ba930e486a0ac.0p-81 }, > + { 0xa80000.0p-24, 0xd7a94b.0p-25, -0x1b6e645f31549e.0p-79 }, > + { 0xa70000.0p-24, 0xdab7d0.0p-25, 0x1118a425494b61.0p-80 }, > + { 0xa68000.0p-24, 0xdc40d5.0p-25, 0x1966f24d29d3a3.0p-80 }, > + { 0xa58000.0p-24, 0xdf566d.0p-25, -0x1d8e52eb2248f1.0p-82 }, > + { 0xa48000.0p-24, 0xe270ce.0p-25, -0x1ee370f96e6b68.0p-80 }, > + { 0xa40000.0p-24, 0xe3ffce.0p-25, 0x1d155324911f57.0p-80 }, > + { 0xa30000.0p-24, 0xe72179.0p-25, -0x1fe6e2f2f867d9.0p-80 }, > + { 0xa20000.0p-24, 0xea4812.0p-25, 0x1b7be9add7f4d4.0p-80 }, > + { 0xa18000.0p-24, 0xebdd3d.0p-25, 0x1b3cfb3f7511dd.0p-79 }, > + { 0xa08000.0p-24, 0xef0b5b.0p-25, -0x1220de1f730190.0p-79 }, > + { 0xa00000.0p-24, 0xf0a451.0p-25, -0x176364c9ac81cd.0p-80 }, > + { 0x9f0000.0p-24, 0xf3da16.0p-25, 0x1eed6b9aafac8d.0p-81 }, > + { 0x9e8000.0p-24, 0xf576e9.0p-25, 0x1d593218675af2.0p-79 }, > + { 0x9d8000.0p-24, 0xf8b47c.0p-25, -0x13e8eb7da053e0.0p-84 }, > + { 0x9d0000.0p-24, 0xfa553f.0p-25, 0x1c063259bcade0.0p-79 }, > + { 0x9c0000.0p-24, 0xfd9ac5.0p-25, 0x1ef491085fa3c1.0p-79 }, > + { 0x9b8000.0p-24, 0xff3f8c.0p-25, 0x1d607a7c2b8c53.0p-79 }, > + { 0x9a8000.0p-24, 0x814697.0p-24, -0x12ad3817004f3f.0p-78 }, > + { 0x9a0000.0p-24, 0x821b06.0p-24, -0x189fc53117f9e5.0p-81 }, > + { 0x990000.0p-24, 0x83c5f8.0p-24, 0x14cf15a048907b.0p-79 }, > + { 0x988000.0p-24, 0x849c7d.0p-24, 0x1cbb1d35fb8287.0p-78 }, > + { 0x978000.0p-24, 0x864ba6.0p-24, 0x1128639b814f9c.0p-78 }, > + { 0x970000.0p-24, 0x87244c.0p-24, 0x184733853300f0.0p-79 }, > + { 0x968000.0p-24, 0x87fdaa.0p-24, 0x109d23aef77dd6.0p-80 }, > + { 0x958000.0p-24, 0x89b293.0p-24, -0x1a81ef367a59de.0p-78 }, > + { 0x950000.0p-24, 0x8a8e20.0p-24, -0x121ad3dbb2f452.0p-78 }, > + { 0x948000.0p-24, 0x8b6a6a.0p-24, -0x1cfb981628af72.0p-79 }, > + { 0x938000.0p-24, 0x8d253a.0p-24, -0x1d21730ea76cfe.0p-79 }, > + { 0x930000.0p-24, 0x8e03c2.0p-24, 0x135cc00e566f77.0p-78 }, > + { 0x928000.0p-24, 0x8ee30d.0p-24, -0x10fcb5df257a26.0p-80 }, > + { 0x918000.0p-24, 0x90a3ee.0p-24, -0x16e171b15433d7.0p-79 }, > + { 0x910000.0p-24, 0x918587.0p-24, -0x1d050da07f3237.0p-79 }, > + { 0x908000.0p-24, 0x9267e7.0p-24, 0x1be03669a5268d.0p-79 }, > + { 0x8f8000.0p-24, 0x942f04.0p-24, 0x10b28e0e26c337.0p-79 }, > + { 0x8f0000.0p-24, 0x9513c3.0p-24, 0x1a1d820da57cf3.0p-78 }, > + { 0x8e8000.0p-24, 0x95f950.0p-24, -0x19ef8f13ae3cf1.0p-79 }, > + { 0x8e0000.0p-24, 0x96dfab.0p-24, -0x109e417a6e507c.0p-78 }, > + { 0x8d0000.0p-24, 0x98aed2.0p-24, 0x10d01a2c5b0e98.0p-79 }, > + { 0x8c8000.0p-24, 0x9997a2.0p-24, -0x1d6a50d4b61ea7.0p-78 }, > + { 0x8c0000.0p-24, 0x9a8145.0p-24, 0x1b3b190b83f952.0p-78 }, > + { 0x8b8000.0p-24, 0x9b6bbf.0p-24, 0x13a69fad7e7abe.0p-78 }, > + { 0x8b0000.0p-24, 0x9c5711.0p-24, -0x11cd12316f576b.0p-78 }, > + { 0x8a8000.0p-24, 0x9d433b.0p-24, 0x1c95c444b807a2.0p-79 }, > + { 0x898000.0p-24, 0x9f1e22.0p-24, -0x1b9c224ea698c3.0p-79 }, > + { 0x890000.0p-24, 0xa00ce1.0p-24, 0x125ca93186cf0f.0p-81 }, > + { 0x888000.0p-24, 0xa0fc80.0p-24, -0x1ee38a7bc228b3.0p-79 }, > + { 0x880000.0p-24, 0xa1ed00.0p-24, -0x1a0db876613d20.0p-78 }, > + { 0x878000.0p-24, 0xa2de62.0p-24, 0x193224e8516c01.0p-79 }, > + { 0x870000.0p-24, 0xa3d0a9.0p-24, 0x1fa28b4d2541ad.0p-79 }, > + { 0x868000.0p-24, 0xa4c3d6.0p-24, 0x1c1b5760fb4572.0p-78 }, > + { 0x858000.0p-24, 0xa6acea.0p-24, 0x1fed5d0f65949c.0p-80 }, > + { 0x850000.0p-24, 0xa7a2d4.0p-24, 0x1ad270c9d74936.0p-80 }, > + { 0x848000.0p-24, 0xa899ab.0p-24, 0x199ff15ce53266.0p-79 }, > + { 0x840000.0p-24, 0xa99171.0p-24, 0x1a19e15ccc45d2.0p-79 }, > + { 0x838000.0p-24, 0xaa8a28.0p-24, -0x121a14ec532b36.0p-80 }, > + { 0x830000.0p-24, 0xab83d1.0p-24, 0x1aee319980bff3.0p-79 }, > + { 0x828000.0p-24, 0xac7e6f.0p-24, -0x18ffd9e3900346.0p-80 }, > + { 0x820000.0p-24, 0xad7a03.0p-24, -0x1e4db102ce29f8.0p-80 }, > + { 0x818000.0p-24, 0xae768f.0p-24, 0x17c35c55a04a83.0p-81 }, > + { 0x810000.0p-24, 0xaf7415.0p-24, 0x1448324047019b.0p-78 }, > + { 0x808000.0p-24, 0xb07298.0p-24, -0x1750ee3915a198.0p-78 }, > + { 0x800000.0p-24, 0xb17218.0p-24, -0x105c610ca86c39.0p-81 }, > +}; > + > +#ifdef USE_UTAB > +static const struct { > + float H; /* 1 + i/INTERVALS (exact) */ > + float E; /* H(i) * G(i) - 1 (exact) */ > +} U[TSIZE] =3D { > + { 0x800000.0p-23, 0 }, > + { 0x810000.0p-23, -0x800000.0p-37 }, > + { 0x820000.0p-23, -0x800000.0p-35 }, > + { 0x830000.0p-23, -0x900000.0p-34 }, > + { 0x840000.0p-23, -0x800000.0p-33 }, > + { 0x850000.0p-23, -0xc80000.0p-33 }, > + { 0x860000.0p-23, -0xa00000.0p-36 }, > + { 0x870000.0p-23, 0x940000.0p-33 }, > + { 0x880000.0p-23, 0x800000.0p-35 }, > + { 0x890000.0p-23, -0xc80000.0p-34 }, > + { 0x8a0000.0p-23, 0xe00000.0p-36 }, > + { 0x8b0000.0p-23, 0x900000.0p-33 }, > + { 0x8c0000.0p-23, -0x800000.0p-35 }, > + { 0x8d0000.0p-23, -0xe00000.0p-33 }, > + { 0x8e0000.0p-23, 0x880000.0p-33 }, > + { 0x8f0000.0p-23, -0xa80000.0p-34 }, > + { 0x900000.0p-23, -0x800000.0p-35 }, > + { 0x910000.0p-23, 0x800000.0p-37 }, > + { 0x920000.0p-23, 0x900000.0p-35 }, > + { 0x930000.0p-23, 0xd00000.0p-35 }, > + { 0x940000.0p-23, 0xe00000.0p-35 }, > + { 0x950000.0p-23, 0xc00000.0p-35 }, > + { 0x960000.0p-23, 0xe00000.0p-36 }, > + { 0x970000.0p-23, -0x800000.0p-38 }, > + { 0x980000.0p-23, -0xc00000.0p-35 }, > + { 0x990000.0p-23, -0xd00000.0p-34 }, > + { 0x9a0000.0p-23, 0x880000.0p-33 }, > + { 0x9b0000.0p-23, 0xe80000.0p-35 }, > + { 0x9c0000.0p-23, -0x800000.0p-35 }, > + { 0x9d0000.0p-23, 0xb40000.0p-33 }, > + { 0x9e0000.0p-23, 0x880000.0p-34 }, > + { 0x9f0000.0p-23, -0xe00000.0p-35 }, > + { 0xa00000.0p-23, 0x800000.0p-33 }, > + { 0xa10000.0p-23, -0x900000.0p-36 }, > + { 0xa20000.0p-23, -0xb00000.0p-33 }, > + { 0xa30000.0p-23, -0xa00000.0p-36 }, > + { 0xa40000.0p-23, 0x800000.0p-33 }, > + { 0xa50000.0p-23, -0xf80000.0p-35 }, > + { 0xa60000.0p-23, 0x880000.0p-34 }, > + { 0xa70000.0p-23, -0x900000.0p-33 }, > + { 0xa80000.0p-23, -0x800000.0p-35 }, > + { 0xa90000.0p-23, 0x900000.0p-34 }, > + { 0xaa0000.0p-23, 0xa80000.0p-33 }, > + { 0xab0000.0p-23, -0xac0000.0p-34 }, > + { 0xac0000.0p-23, -0x800000.0p-37 }, > + { 0xad0000.0p-23, 0xf80000.0p-35 }, > + { 0xae0000.0p-23, 0xf80000.0p-34 }, > + { 0xaf0000.0p-23, -0xac0000.0p-33 }, > + { 0xb00000.0p-23, -0x800000.0p-33 }, > + { 0xb10000.0p-23, -0xb80000.0p-34 }, > + { 0xb20000.0p-23, -0x800000.0p-34 }, > + { 0xb30000.0p-23, -0xb00000.0p-35 }, > + { 0xb40000.0p-23, -0x800000.0p-35 }, > + { 0xb50000.0p-23, -0xe00000.0p-36 }, > + { 0xb60000.0p-23, -0x800000.0p-35 }, > + { 0xb70000.0p-23, -0xb00000.0p-35 }, > + { 0xb80000.0p-23, -0x800000.0p-34 }, > + { 0xb90000.0p-23, -0xb80000.0p-34 }, > + { 0xba0000.0p-23, -0x800000.0p-33 }, > + { 0xbb0000.0p-23, -0xac0000.0p-33 }, > + { 0xbc0000.0p-23, 0x980000.0p-33 }, > + { 0xbd0000.0p-23, 0xbc0000.0p-34 }, > + { 0xbe0000.0p-23, 0xe00000.0p-36 }, > + { 0xbf0000.0p-23, -0xb80000.0p-35 }, > + { 0xc00000.0p-23, -0x800000.0p-33 }, > + { 0xc10000.0p-23, 0xa80000.0p-33 }, > + { 0xc20000.0p-23, 0x900000.0p-34 }, > + { 0xc30000.0p-23, -0x800000.0p-35 }, > + { 0xc40000.0p-23, -0x900000.0p-33 }, > + { 0xc50000.0p-23, 0x820000.0p-33 }, > + { 0xc60000.0p-23, 0x800000.0p-38 }, > + { 0xc70000.0p-23, -0x820000.0p-33 }, > + { 0xc80000.0p-23, 0x800000.0p-33 }, > + { 0xc90000.0p-23, -0xa00000.0p-36 }, > + { 0xca0000.0p-23, -0xb00000.0p-33 }, > + { 0xcb0000.0p-23, 0x840000.0p-34 }, > + { 0xcc0000.0p-23, -0xd00000.0p-34 }, > + { 0xcd0000.0p-23, 0x800000.0p-33 }, > + { 0xce0000.0p-23, -0xe00000.0p-35 }, > + { 0xcf0000.0p-23, 0xa60000.0p-33 }, > + { 0xd00000.0p-23, -0x800000.0p-35 }, > + { 0xd10000.0p-23, 0xb40000.0p-33 }, > + { 0xd20000.0p-23, -0x800000.0p-35 }, > + { 0xd30000.0p-23, 0xaa0000.0p-33 }, > + { 0xd40000.0p-23, -0xe00000.0p-35 }, > + { 0xd50000.0p-23, 0x880000.0p-33 }, > + { 0xd60000.0p-23, -0xd00000.0p-34 }, > + { 0xd70000.0p-23, 0x9c0000.0p-34 }, > + { 0xd80000.0p-23, -0xb00000.0p-33 }, > + { 0xd90000.0p-23, -0x800000.0p-38 }, > + { 0xda0000.0p-23, 0xa40000.0p-33 }, > + { 0xdb0000.0p-23, -0xdc0000.0p-34 }, > + { 0xdc0000.0p-23, 0xc00000.0p-35 }, > + { 0xdd0000.0p-23, 0xca0000.0p-33 }, > + { 0xde0000.0p-23, -0xb80000.0p-34 }, > + { 0xdf0000.0p-23, 0xd00000.0p-35 }, > + { 0xe00000.0p-23, 0xc00000.0p-33 }, > + { 0xe10000.0p-23, -0xf40000.0p-34 }, > + { 0xe20000.0p-23, 0x800000.0p-37 }, > + { 0xe30000.0p-23, 0x860000.0p-33 }, > + { 0xe40000.0p-23, -0xc80000.0p-33 }, > + { 0xe50000.0p-23, -0xa80000.0p-34 }, > + { 0xe60000.0p-23, 0xe00000.0p-36 }, > + { 0xe70000.0p-23, 0x880000.0p-33 }, > + { 0xe80000.0p-23, -0xe00000.0p-33 }, > + { 0xe90000.0p-23, -0xfc0000.0p-34 }, > + { 0xea0000.0p-23, -0x800000.0p-35 }, > + { 0xeb0000.0p-23, 0xe80000.0p-35 }, > + { 0xec0000.0p-23, 0x900000.0p-33 }, > + { 0xed0000.0p-23, 0xe20000.0p-33 }, > + { 0xee0000.0p-23, -0xac0000.0p-33 }, > + { 0xef0000.0p-23, -0xc80000.0p-34 }, > + { 0xf00000.0p-23, -0x800000.0p-35 }, > + { 0xf10000.0p-23, 0x800000.0p-35 }, > + { 0xf20000.0p-23, 0xb80000.0p-34 }, > + { 0xf30000.0p-23, 0x940000.0p-33 }, > + { 0xf40000.0p-23, 0xc80000.0p-33 }, > + { 0xf50000.0p-23, -0xf20000.0p-33 }, > + { 0xf60000.0p-23, -0xc80000.0p-33 }, > + { 0xf70000.0p-23, -0xa20000.0p-33 }, > + { 0xf80000.0p-23, -0x800000.0p-33 }, > + { 0xf90000.0p-23, -0xc40000.0p-34 }, > + { 0xfa0000.0p-23, -0x900000.0p-34 }, > + { 0xfb0000.0p-23, -0xc80000.0p-35 }, > + { 0xfc0000.0p-23, -0x800000.0p-35 }, > + { 0xfd0000.0p-23, -0x900000.0p-36 }, > + { 0xfe0000.0p-23, -0x800000.0p-37 }, > + { 0xff0000.0p-23, -0x800000.0p-39 }, > + { 0x800000.0p-22, 0 }, > +}; > +#endif /* USE_UTAB */ > + > +#ifdef STRUCT_RETURN > +#define RETURN1(rp, v) do { \ > + (rp)->hi =3D (v); \ > + (rp)->lo_set =3D 0; \ > + return; \ > +} while (0) > + > +#define RETURN2(rp, h, l) do { \ > + (rp)->hi =3D (h); \ > + (rp)->lo =3D (l); \ > + (rp)->lo_set =3D 1; \ > + return; \ > +} while (0) > + > +struct ld { > + long double hi; > + long double lo; > + int lo_set; > +}; > +#else > +#define RETURN1(rp, v) RETURNF(v) > +#define RETURN2(rp, h, l) RETURNI((h) + (l)) > +#endif > + > +#ifdef STRUCT_RETURN > +static inline __always_inline void > +k_logl(long double x, struct ld *rp) > +#else > +long double > +logl(long double x) > +#endif > +{ > + long double d, dk, val_hi, val_lo, z; > + uint64_t ix, lx; > + int i, k; > + uint16_t hx; > + > + EXTRACT_LDBL80_WORDS(hx, lx, x); > + k =3D -16383; > +#if 0 /* Hard to do efficiently. Don't do it until we support all modes= . */ > + if (x =3D=3D 1) > + RETURN1(rp, 0); /* log(1) =3D +0 in all rounding mo= des */ > +#endif > + if (hx =3D=3D 0 || hx >=3D 0x8000) { /* zero, negative or subnorma= l? */ > + if (((hx & 0x7fff) | lx) =3D=3D 0) > + RETURN1(rp, -1 / zero); /* log(+-0) =3D -Inf */ > + if (hx !=3D 0) > + /* log(neg or [pseudo-]NaN) =3D qNaN: */ > + RETURN1(rp, (x - x) / zero); > + x *=3D 0x1.0p65; /* subnormal; scale up x */ > + /* including pseudo-subnormals */ > + EXTRACT_LDBL80_WORDS(hx, lx, x); > + k =3D -16383 - 65; > + } else if (hx >=3D 0x7fff || (lx & 0x8000000000000000ULL) =3D=3D 0) > + RETURN1(rp, x + x); /* log(Inf or NaN) =3D Inf or qNaN = */ > + /* log(pseudo-Inf) =3D qNaN */ > + /* log(pseudo-NaN) =3D qNaN */ > + /* log(unnormal) =3D qNaN */ > +#ifndef STRUCT_RETURN > + ENTERI(); > +#endif > + k +=3D hx; > + ix =3D lx & 0x7fffffffffffffffULL; > + dk =3D k; > + > + /* Scale x to be in [1, 2). */ > + SET_LDBL_EXPSIGN(x, 0x3fff); > + > + /* 0 <=3D i <=3D INTERVALS: */ > +#define L2I (64 - LOG2_INTERVALS) > + i =3D (ix + (1LL << (L2I - 2))) >> (L2I - 1); > + > + /* > + * -0.005280 < d < 0.004838. In particular, the infinite- > + * precision |d| is <=3D 2**-7. Rounding of G(i) to 8 bits > + * ensures that d is representable without extra precision for > + * this bound on |d| (since when this calculation is expressed > + * as x*G(i)-1, the multiplication needs as many extra bits as > + * G(i) has and the subtraction cancels 8 bits). But for > + * most i (107 cases out of 129), the infinite-precision |d| > + * is <=3D 2**-8. G(i) is rounded to 9 bits for such i to give > + * better accuracy (this works by improving the bound on |d|, > + * which in turn allows rounding to 9 bits in more cases). > + * This is only important when the original x is near 1 -- it > + * lets us avoid using a special method to give the desired > + * accuracy for such x. > + */ > + if (0) > + d =3D x * G(i) - 1; > + else { > +#ifdef USE_UTAB > + d =3D (x - H(i)) * G(i) + E(i); > +#else > + long double x_hi, x_lo; > + float fx_hi; > + > + /* > + * Split x into x_hi + x_lo to calculate x*G(i)-1 exactly. > + * G(i) has at most 9 bits, so the splitting point is not > + * critical. > + */ > + SET_FLOAT_WORD(fx_hi, (lx >> 40) | 0x3f800000); > + x_hi =3D fx_hi; > + x_lo =3D x - x_hi; > + d =3D x_hi * G(i) - 1 + x_lo * G(i); > +#endif > + } > + > + /* > + * Our algorithm depends on exact cancellation of F_lo(i) and > + * F_hi(i) with dk*ln_2_lo and dk*ln2_hi when k is -1 and i is > + * at the end of the table. This and other technical complications > + * make it difficult to avoid the double scaling in (dk*ln2) * > + * log(base) for base !=3D e without losing more accuracy and/or > + * efficiency than is gained. > + */ > + z =3D d * d; > + val_lo =3D z * d * z * (z * (d * P8 + P7) + (d * P6 + P5)) + > + (F_lo(i) + dk * ln2_lo + z * d * (d * P4 + P3)) + z * P2; > + val_hi =3D d; > +#ifdef DEBUG > + if (fetestexcept(FE_UNDERFLOW)) > + breakpoint(); > +#endif > + > + _3sumF(val_hi, val_lo, F_hi(i) + dk * ln2_hi); > + RETURN2(rp, val_hi, val_lo); > +} > + > +long double > +log1pl(long double x) > +{ > + long double d, d_hi, d_lo, dk, f_lo, val_hi, val_lo, z; > + long double f_hi, twopminusk; > + uint64_t ix, lx; > + int i, k; > + int16_t ax, hx; > + > + DOPRINT_START(&x); > + EXTRACT_LDBL80_WORDS(hx, lx, x); > + if (hx < 0x3fff) { /* x < 1, or x neg NaN */ > + ax =3D hx & 0x7fff; > + if (ax >=3D 0x3fff) { /* x <=3D -1, or x neg NaN */ > + if (ax =3D=3D 0x3fff && lx =3D=3D 0x800000000000000= 0ULL) > + RETURNP(-1 / zero); /* log1p(-1) =3D -I= nf */ > + /* log1p(x < 1, or x [pseudo-]NaN) =3D qNaN: */ > + RETURNP((x - x) / (x - x)); > + } > + if (ax <=3D 0x3fbe) { /* |x| < 2**-64 */ > + if ((int)x =3D=3D 0) > + RETURNP(x); /* x with inexact if x !=3D= 0 */ > + } > + f_hi =3D 1; > + f_lo =3D x; > + } else if (hx >=3D 0x7fff) { /* x +Inf or non-neg NaN */ > + RETURNP(x + x); /* log1p(Inf or NaN) =3D Inf or qNa= N */ > + /* log1p(pseudo-Inf) =3D qNaN */ > + /* log1p(pseudo-NaN) =3D qNaN */ > + /* log1p(unnormal) =3D qNaN */ > + } else if (hx < 0x407f) { /* 1 <=3D x < 2**128 */ > + f_hi =3D x; > + f_lo =3D 1; > + } else { /* 2**128 <=3D x < +Inf */ > + f_hi =3D x; > + f_lo =3D 0; /* avoid underflow of the P5 term= */ > + } > + ENTERI(); > + x =3D f_hi + f_lo; > + f_lo =3D (f_hi - x) + f_lo; > + > + EXTRACT_LDBL80_WORDS(hx, lx, x); > + k =3D -16383; > + > + k +=3D hx; > + ix =3D lx & 0x7fffffffffffffffULL; > + dk =3D k; > + > + SET_LDBL_EXPSIGN(x, 0x3fff); > + twopminusk =3D 1; > + SET_LDBL_EXPSIGN(twopminusk, 0x7ffe - (hx & 0x7fff)); > + f_lo *=3D twopminusk; > + > + i =3D (ix + (1LL << (L2I - 2))) >> (L2I - 1); > + > + /* > + * x*G(i)-1 (with a reduced x) can be represented exactly, as > + * above, but now we need to evaluate the polynomial on d =3D > + * (x+f_lo)*G(i)-1 and extra precision is needed for that. > + * Since x+x_lo is a hi+lo decomposition and subtracting 1 > + * doesn't lose too many bits, an inexact calculation for > + * f_lo*G(i) is good enough. > + */ > + if (0) > + d_hi =3D x * G(i) - 1; > + else { > +#ifdef USE_UTAB > + d_hi =3D (x - H(i)) * G(i) + E(i); > +#else > + long double x_hi, x_lo; > + float fx_hi; > + > + SET_FLOAT_WORD(fx_hi, (lx >> 40) | 0x3f800000); > + x_hi =3D fx_hi; > + x_lo =3D x - x_hi; > + d_hi =3D x_hi * G(i) - 1 + x_lo * G(i); > +#endif > + } > + d_lo =3D f_lo * G(i); > + > + /* > + * This is _2sumF(d_hi, d_lo) inlined. The condition > + * (d_hi =3D=3D 0 || |d_hi| >=3D |d_lo|) for using _2sumF() is not > + * always satisifed, so it is not clear that this works, but > + * it works in practice. It works even if it gives a wrong > + * normalized d_lo, since |d_lo| > |d_hi| implies that i is > + * nonzero and d is tiny, so the F(i) term dominates d_lo. > + * In float precision: > + * (By exhaustive testing, the worst case is d_hi =3D 0x1.bp-25. > + * And if d is only a little tinier than that, we would have > + * another underflow problem for the P3 term; this is also ruled > + * out by exhaustive testing.) > + */ > + d =3D d_hi + d_lo; > + d_lo =3D d_hi - d + d_lo; > + d_hi =3D d; > + > + z =3D d * d; > + val_lo =3D z * d * z * (z * (d * P8 + P7) + (d * P6 + P5)) + > + (F_lo(i) + dk * ln2_lo + d_lo + z * d * (d * P4 + P3)) + z * P2= ; > + val_hi =3D d_hi; > +#ifdef DEBUG > + if (fetestexcept(FE_UNDERFLOW)) > + breakpoint(); > +#endif > + > + _3sumF(val_hi, val_lo, F_hi(i) + dk * ln2_hi); > + RETURN2PI(val_hi, val_lo); > +} > + > +#ifdef STRUCT_RETURN > + > +long double > +logl(long double x) > +{ > + struct ld r; > + > + ENTERI(); > + DOPRINT_START(&x); > + k_logl(x, &r); > + RETURNSPI(&r); > +} > + > +/* Use macros since GCC < 8 rejects static const expressions in initiali= zers. */ > +#define invln10_hi 4.3429448190317999e-1 /* 0x1bcb7b1526e00= 0.0p-54 */ > +#define invln10_lo 7.1842412889749798e-14 /* 0x1438ca9aadd55= 8.0p-96 */ > +#define invln2_hi 1.4426950408887933e0 /* 0x171547652b800= 0.0p-52 */ > +#define invln2_lo 1.7010652264631490e-13 /* 0x17f0bbbe87fed= 0.0p-95 */ > +/* Let the compiler pre-calculate this sum to avoid FE_INEXACT at run ti= me. */ > +static const double invln10_lo_plus_hi =3D invln10_lo + invln10_hi; > +static const double invln2_lo_plus_hi =3D invln2_lo + invln2_hi; > + > +long double > +log10l(long double x) > +{ > + struct ld r; > + long double hi, lo; > + > + ENTERI(); > + DOPRINT_START(&x); > + k_logl(x, &r); > + if (!r.lo_set) > + RETURNPI(r.hi); > + _2sumF(r.hi, r.lo); > + hi =3D (float)r.hi; > + lo =3D r.lo + (r.hi - hi); > + RETURN2PI(invln10_hi * hi, > + invln10_lo_plus_hi * lo + invln10_lo * hi); > +} > + > +long double > +log2l(long double x) > +{ > + struct ld r; > + long double hi, lo; > + > + ENTERI(); > + DOPRINT_START(&x); > + k_logl(x, &r); > + if (!r.lo_set) > + RETURNPI(r.hi); > + _2sumF(r.hi, r.lo); > + hi =3D (float)r.hi; > + lo =3D r.lo + (r.hi - hi); > + RETURN2PI(invln2_hi * hi, > + invln2_lo_plus_hi * lo + invln2_lo * hi); > +} > + > +#endif /* STRUCT_RETURN */ > diff --git a/newlib/libm/ld80/s_sinpil.c b/newlib/libm/ld80/s_sinpil.c > new file mode 100644 > index 000000000..4cefa9235 > --- /dev/null > +++ b/newlib/libm/ld80/s_sinpil.c > @@ -0,0 +1,140 @@ > +/*- > + * Copyright (c) 2017 Steven G. Kargl > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice unmodified, this list of conditions, and the following > + * disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in th= e > + * documentation and/or other materials provided with the distributio= n. > + * > + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES > + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. > + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT > + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, > + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY > + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF > + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +/* > + * See ../src/s_sinpi.c for implementation details. > + */ > + > +#ifdef __i386__ > +#include > +#endif > +#include > + > +#include "fpmath.h" > +#include "math.h" > +#include "math_private.h" > + > +static const union IEEEl2bits > +pi_hi_u =3D LD80C(0xc90fdaa200000000, 1, 3.14159265346825122833e+00L), > +pi_lo_u =3D LD80C(0x85a308d313198a2e, -33, 1.21542010130123852029e-10L); > +#define pi_hi (pi_hi_u.e) > +#define pi_lo (pi_lo_u.e) > + > +#include "k_cospil.h" > +#include "k_sinpil.h" > + > +volatile static const double vzero =3D 0; > + > +long double > +sinpil(long double x) > +{ > + long double ax, hi, lo, s; > + uint64_t lx, m; > + uint32_t j0; > + uint16_t hx, ix; > + > + EXTRACT_LDBL80_WORDS(hx, lx, x); > + ix =3D hx & 0x7fff; > + INSERT_LDBL80_WORDS(ax, ix, lx); > + > + ENTERI(); > + > + if (ix < 0x3fff) { /* |x| < 1 */ > + if (ix < 0x3ffd) { /* |x| < 0.25 */ > + if (ix < 0x3fdd) { /* |x| < 0x1p-34 */ > + if (x =3D=3D 0) > + RETURNI(x); > + INSERT_LDBL80_WORDS(hi, hx, > + lx & 0xffffffff00000000ull); > + hi *=3D 0x1p63L; > + lo =3D x * 0x1p63L - hi; > + s =3D (pi_lo + pi_hi) * lo + pi_lo * hi + > + pi_hi * hi; > + RETURNI(s * 0x1p-63L); > + } > + s =3D __kernel_sinpil(ax); > + RETURNI((hx & 0x8000) ? -s : s); > + } > + > + if (ix < 0x3ffe) /* |x| < 0.5 */ > + s =3D __kernel_cospil(0.5 - ax); > + else if (lx < 0xc000000000000000ull) /* |x| < 0.75 */ > + s =3D __kernel_cospil(ax - 0.5); > + else > + s =3D __kernel_sinpil(1 - ax); > + RETURNI((hx & 0x8000) ? -s : s); > + } > + > + if (ix < 0x403e) { /* 1 <=3D |x| < 0x1p63 */ > + /* Determine integer part of ax. */ > + j0 =3D ix - 0x3fff + 1; > + if (j0 < 32) { > + lx =3D (lx >> 32) << 32; > + lx &=3D ~(((lx << 32)-1) >> j0); > + } else { > + m =3D (uint64_t)-1 >> (j0 + 1); > + if (lx & m) lx &=3D ~m; > + } > + INSERT_LDBL80_WORDS(x, ix, lx); > + > + ax -=3D x; > + EXTRACT_LDBL80_WORDS(ix, lx, ax); > + > + if (ix =3D=3D 0) { > + s =3D 0; > + } else { > + if (ix < 0x3ffe) { /* |x| < 0.5 */ > + if (ix < 0x3ffd) /* |x| < 0.25 */ > + s =3D __kernel_sinpil(ax); > + else > + s =3D __kernel_cospil(0.5 - ax); > + } else { > + /* |x| < 0.75 */ > + if (lx < 0xc000000000000000ull) > + s =3D __kernel_cospil(ax - 0.5); > + else > + s =3D __kernel_sinpil(1 - ax); > + } > + > + if (j0 > 40) > + x -=3D 0x1p40; > + if (j0 > 30) > + x -=3D 0x1p30; > + j0 =3D (uint32_t)x; > + if (j0 & 1) s =3D -s; > + } > + RETURNI((hx & 0x8000) ? -s : s); > + } > + > + /* x =3D +-inf or nan. */ > + if (ix >=3D 0x7fff) > + RETURNI(vzero / vzero); > + > + /* > + * |x| >=3D 0x1p63 is always an integer, so return +-0. > + */ > + RETURNI(copysignl(0, x)); > +} > -- > 2.31.1