brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.1 KiB · d390591 Raw
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