202 lines · plain
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#if __CLC_FPSIZE == 3210 11_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_sinh(__CLC_GENTYPE x) {12 // After dealing with special cases the computation is split into regions as13 // follows. abs(x) >= max_sinh_arg: sinh(x) = sign(x)*Inf abs(x) >=14 // small_threshold: sinh(x) = sign(x)*exp(abs(x))/2 computed using the15 // splitexp and scaleDouble functions as for exp_amd(). abs(x) <16 // small_threshold: compute p = exp(y) - 1 and then z = 0.5*(p+(p/(p+1.0)))17 // sinh(x) is then sign(x)*z.18 19 const __CLC_GENTYPE max_sinh_arg = 0x1.65a9fap+6f;20 const __CLC_GENTYPE small_threshold = 0x1.0a2b24p+3f;21 22 __CLC_UINTN ux = __CLC_AS_UINTN(x);23 __CLC_GENTYPE y = __clc_fabs(x);24 __CLC_UINTN aux = __CLC_AS_UINTN(y);25 __CLC_UINTN xs = ux ^ aux;26 27 // We find the integer part y0 of y and the increment dy = y - y0. We then28 // compute z = sinh(y) = sinh(y0)cosh(dy) + cosh(y0)sinh(dy) where sinh(y0)29 // and cosh(y0) are tabulated above.30 __CLC_INTN ind = __CLC_CONVERT_INTN(y);31 ind = __CLC_CONVERT_UINTN(ind) > 36U ? 0 : ind;32 33 __CLC_GENTYPE dy = y - __CLC_CONVERT_GENTYPE(ind);34 __CLC_GENTYPE dy2 = dy * dy;35 36 __CLC_GENTYPE sdy = __clc_mad(37 dy2,38 __clc_mad(39 dy2,40 __clc_mad(41 dy2,42 __clc_mad(43 dy2,44 __clc_mad(dy2,45 __clc_mad(dy2, 0.7746188980094184251527126e-12f,46 0.160576793121939886190847e-9f),47 0.250521176994133472333666e-7f),48 0.275573191913636406057211e-5f),49 0.198412698413242405162014e-3f),50 0.833333333333329931873097e-2f),51 0.166666666666666667013899e0f);52 sdy = __clc_mad(sdy, dy * dy2, dy);53 54 __CLC_GENTYPE cdy = __clc_mad(55 dy2,56 __clc_mad(57 dy2,58 __clc_mad(59 dy2,60 __clc_mad(61 dy2,62 __clc_mad(dy2,63 __clc_mad(dy2, 0.1163921388172173692062032e-10f,64 0.208744349831471353536305e-8f),65 0.275573350756016588011357e-6f),66 0.248015872460622433115785e-4f),67 0.138888888889814854814536e-2f),68 0.416666666666660876512776e-1f),69 0.500000000000000005911074e0f);70 cdy = __clc_mad(cdy, dy2, 1.0f);71 72 __CLC_GENTYPE sinhcoshh = __CLC_USE_TABLE(sinhcosh_tbl_head, ind);73 __CLC_GENTYPE sinhcosht = __CLC_USE_TABLE(sinhcosh_tbl_tail, ind);74 __CLC_GENTYPE z = __clc_mad(sinhcosht, sdy, sinhcoshh * cdy);75 z = __CLC_AS_GENTYPE(xs | __CLC_AS_UINTN(z));76 77 // When y is large enough so that the negative exponential is negligible,78 // so sinh(y) is approximated by sign(x)*exp(y)/2.79 __CLC_GENTYPE t = __clc_exp(y - 0x1.62e500p-1f);80 __CLC_GENTYPE zsmall = __clc_mad(0x1.a0210ep-18f, t, t);81 zsmall = __CLC_AS_GENTYPE(xs | __CLC_AS_UINTN(zsmall));82 z = y >= small_threshold ? zsmall : z;83 84 // Corner cases85 __CLC_GENTYPE zinf = __CLC_AS_GENTYPE(PINFBITPATT_SP32 | xs);86 z = y >= max_sinh_arg ? zinf : z;87 z = aux > PINFBITPATT_SP32 || aux < 0x38800000U ? x : z;88 89 return z;90}91 92#elif __CLC_FPSIZE == 6493 94_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_sinh(__CLC_GENTYPE x) {95 // After dealing with special cases the computation is split into96 // regions as follows:97 //98 // abs(x) >= max_sinh_arg:99 // sinh(x) = sign(x)*Inf100 //101 // abs(x) >= small_threshold:102 // sinh(x) = sign(x)*exp(abs(x))/2 computed using the103 // splitexp and scaleDouble functions as for exp_amd().104 //105 // abs(x) < small_threshold:106 // compute p = exp(y) - 1 and then z = 0.5*(p+(p/(p+1.0)))107 // sinh(x) is then sign(x)*z.108 109 // 0x408633ce8fb9f87e110 const __CLC_GENTYPE max_sinh_arg = 7.10475860073943977113e+02;111 112 // This is where exp(-x) is insignificant compared to exp(x) = ln(2^27)113 const __CLC_GENTYPE small_threshold = 0x1.2b708872320e2p+4;114 115 __CLC_GENTYPE y = __clc_fabs(x);116 117 // In this range we find the integer part y0 of y118 // and the increment dy = y - y0. We then compute119 // z = sinh(y) = sinh(y0)cosh(dy) + cosh(y0)sinh(dy)120 // where sinh(y0) and cosh(y0) are obtained from tables121 122 __CLC_INTN ind = __clc_min(__CLC_CONVERT_INTN(y), 36);123 __CLC_GENTYPE dy = y - __CLC_CONVERT_GENTYPE(ind);124 __CLC_GENTYPE dy2 = dy * dy;125 126 __CLC_GENTYPE sdy =127 dy * dy2 *128 __clc_fma(129 dy2,130 __clc_fma(131 dy2,132 __clc_fma(133 dy2,134 __clc_fma(135 dy2,136 __clc_fma(dy2,137 __clc_fma(dy2, 0.7746188980094184251527126e-12,138 0.160576793121939886190847e-9),139 0.250521176994133472333666e-7),140 0.275573191913636406057211e-5),141 0.198412698413242405162014e-3),142 0.833333333333329931873097e-2),143 0.166666666666666667013899e0);144 145 __CLC_GENTYPE cdy =146 dy2 *147 __clc_fma(148 dy2,149 __clc_fma(150 dy2,151 __clc_fma(152 dy2,153 __clc_fma(154 dy2,155 __clc_fma(dy2,156 __clc_fma(dy2, 0.1163921388172173692062032e-10,157 0.208744349831471353536305e-8),158 0.275573350756016588011357e-6),159 0.248015872460622433115785e-4),160 0.138888888889814854814536e-2),161 0.416666666666660876512776e-1),162 0.500000000000000005911074e0);163 164 // At this point sinh(dy) is approximated by dy + sdy.165 // Shift some significant bits from dy to sdy.166 __CLC_GENTYPE sdy1 =167 __CLC_AS_GENTYPE(__CLC_AS_ULONGN(dy) & 0xfffffffff8000000UL);168 __CLC_GENTYPE sdy2 = sdy + (dy - sdy1);169 170 __CLC_GENTYPE cl = __CLC_USE_TABLE(cosh_tbl_head, ind);171 __CLC_GENTYPE ct = __CLC_USE_TABLE(cosh_tbl_tail, ind);172 __CLC_GENTYPE sl = __CLC_USE_TABLE(sinh_tbl_head, ind);173 __CLC_GENTYPE st = __CLC_USE_TABLE(sinh_tbl_tail, ind);174 175 __CLC_GENTYPE z =176 __clc_fma(cl, sdy1,177 __clc_fma(sl, cdy,178 __clc_fma(cl, sdy2,179 __clc_fma(ct, sdy1,180 __clc_fma(st, cdy, ct * sdy2)) +181 st))) +182 sl;183 184 // Other cases185 z = (y < 0x1.0p-28) || __clc_isnan(x) || __clc_isinf(x) ? y : z;186 187 __CLC_GENTYPE t = __clc_exp(y - 0x1.62e42fefa3800p-1);188 t = __clc_fma(t, -0x1.ef35793c76641p-45, t);189 z = y >= small_threshold ? t : z;190 z = y >= max_sinh_arg ? __CLC_AS_GENTYPE((__CLC_ULONGN)PINFBITPATT_DP64) : z;191 192 return __clc_copysign(z, x);193}194 195#elif __CLC_FPSIZE == 16196 197_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_sinh(__CLC_GENTYPE x) {198 return __CLC_CONVERT_GENTYPE(__clc_sinh(__CLC_CONVERT_FLOATN(x)));199}200 201#endif202