xref: /reactos/sdk/lib/crt/math/libm_sse2/sinh.c (revision 9e8ed3f8)
14afb647cSTimo Kreuzer 
24afb647cSTimo Kreuzer /*******************************************************************************
34afb647cSTimo Kreuzer MIT License
44afb647cSTimo Kreuzer -----------
54afb647cSTimo Kreuzer 
64afb647cSTimo Kreuzer Copyright (c) 2002-2019 Advanced Micro Devices, Inc.
74afb647cSTimo Kreuzer 
84afb647cSTimo Kreuzer Permission is hereby granted, free of charge, to any person obtaining a copy
94afb647cSTimo Kreuzer of this Software and associated documentaon files (the "Software"), to deal
104afb647cSTimo Kreuzer in the Software without restriction, including without limitation the rights
114afb647cSTimo Kreuzer to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
124afb647cSTimo Kreuzer copies of the Software, and to permit persons to whom the Software is
134afb647cSTimo Kreuzer furnished to do so, subject to the following conditions:
144afb647cSTimo Kreuzer 
154afb647cSTimo Kreuzer The above copyright notice and this permission notice shall be included in
164afb647cSTimo Kreuzer all copies or substantial portions of the Software.
174afb647cSTimo Kreuzer 
184afb647cSTimo Kreuzer THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
194afb647cSTimo Kreuzer IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
204afb647cSTimo Kreuzer FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
214afb647cSTimo Kreuzer AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
224afb647cSTimo Kreuzer LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
234afb647cSTimo Kreuzer OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
244afb647cSTimo Kreuzer THE SOFTWARE.
254afb647cSTimo Kreuzer *******************************************************************************/
264afb647cSTimo Kreuzer 
274afb647cSTimo Kreuzer #include "libm.h"
284afb647cSTimo Kreuzer #include "libm_util.h"
294afb647cSTimo Kreuzer 
304afb647cSTimo Kreuzer #define USE_SPLITEXP
314afb647cSTimo Kreuzer #define USE_SCALEDOUBLE_1
324afb647cSTimo Kreuzer #define USE_SCALEDOUBLE_2
334afb647cSTimo Kreuzer #define USE_INFINITY_WITH_FLAGS
344afb647cSTimo Kreuzer #define USE_VAL_WITH_FLAGS
354afb647cSTimo Kreuzer #define USE_HANDLE_ERROR
364afb647cSTimo Kreuzer #include "libm_inlines.h"
374afb647cSTimo Kreuzer #undef USE_SPLITEXP
384afb647cSTimo Kreuzer #undef USE_SCALEDOUBLE_1
394afb647cSTimo Kreuzer #undef USE_SCALEDOUBLE_2
404afb647cSTimo Kreuzer #undef USE_INFINITY_WITH_FLAGS
414afb647cSTimo Kreuzer #undef USE_VAL_WITH_FLAGS
424afb647cSTimo Kreuzer #undef USE_HANDLE_ERROR
434afb647cSTimo Kreuzer 
444afb647cSTimo Kreuzer #include "libm_errno.h"
454afb647cSTimo Kreuzer 
46*9e8ed3f8STimo Kreuzer #ifdef _MSC_VER
474afb647cSTimo Kreuzer #pragma function(sinh)
48*9e8ed3f8STimo Kreuzer #endif
49*9e8ed3f8STimo Kreuzer 
sinh(double x)504afb647cSTimo Kreuzer double sinh(double x)
514afb647cSTimo Kreuzer {
524afb647cSTimo Kreuzer   /*
534afb647cSTimo Kreuzer     After dealing with special cases the computation is split into
544afb647cSTimo Kreuzer     regions as follows:
554afb647cSTimo Kreuzer 
564afb647cSTimo Kreuzer     abs(x) >= max_sinh_arg:
574afb647cSTimo Kreuzer     sinh(x) = sign(x)*Inf
584afb647cSTimo Kreuzer 
594afb647cSTimo Kreuzer     abs(x) >= small_threshold:
604afb647cSTimo Kreuzer     sinh(x) = sign(x)*exp(abs(x))/2 computed using the
614afb647cSTimo Kreuzer     splitexp and scaleDouble functions as for exp_amd().
624afb647cSTimo Kreuzer 
634afb647cSTimo Kreuzer     abs(x) < small_threshold:
644afb647cSTimo Kreuzer     compute p = exp(y) - 1 and then z = 0.5*(p+(p/(p+1.0)))
654afb647cSTimo Kreuzer     sinh(x) is then sign(x)*z.                             */
664afb647cSTimo Kreuzer 
674afb647cSTimo Kreuzer   static const double
684afb647cSTimo Kreuzer     max_sinh_arg = 7.10475860073943977113e+02, /* 0x408633ce8fb9f87e */
694afb647cSTimo Kreuzer     thirtytwo_by_log2 = 4.61662413084468283841e+01, /* 0x40471547652b82fe */
704afb647cSTimo Kreuzer     log2_by_32_lead = 2.16608493356034159660e-02, /* 0x3f962e42fe000000 */
714afb647cSTimo Kreuzer     log2_by_32_tail = 5.68948749532545630390e-11, /* 0x3dcf473de6af278e */
724afb647cSTimo Kreuzer     small_threshold = 8*BASEDIGITS_DP64*0.30102999566398119521373889;
734afb647cSTimo Kreuzer   /* (8*BASEDIGITS_DP64*log10of2) ' exp(-x) insignificant c.f. exp(x) */
744afb647cSTimo Kreuzer 
754afb647cSTimo Kreuzer   /* Lead and tail tabulated values of sinh(i) and cosh(i)
764afb647cSTimo Kreuzer      for i = 0,...,36. The lead part has 26 leading bits. */
774afb647cSTimo Kreuzer 
784afb647cSTimo Kreuzer   static const double sinh_lead[37] = {
794afb647cSTimo Kreuzer     0.00000000000000000000e+00,  /* 0x0000000000000000 */
804afb647cSTimo Kreuzer     1.17520117759704589844e+00,  /* 0x3ff2cd9fc0000000 */
814afb647cSTimo Kreuzer     3.62686038017272949219e+00,  /* 0x400d03cf60000000 */
824afb647cSTimo Kreuzer     1.00178747177124023438e+01,  /* 0x40240926e0000000 */
834afb647cSTimo Kreuzer     2.72899169921875000000e+01,  /* 0x403b4a3800000000 */
844afb647cSTimo Kreuzer     7.42032089233398437500e+01,  /* 0x40528d0160000000 */
854afb647cSTimo Kreuzer     2.01713153839111328125e+02,  /* 0x406936d228000000 */
864afb647cSTimo Kreuzer     5.48316116333007812500e+02,  /* 0x4081228768000000 */
874afb647cSTimo Kreuzer     1.49047882080078125000e+03,  /* 0x409749ea50000000 */
884afb647cSTimo Kreuzer     4.05154187011718750000e+03,  /* 0x40afa71570000000 */
894afb647cSTimo Kreuzer     1.10132326660156250000e+04,  /* 0x40c5829dc8000000 */
904afb647cSTimo Kreuzer     2.99370708007812500000e+04,  /* 0x40dd3c4488000000 */
914afb647cSTimo Kreuzer     8.13773945312500000000e+04,  /* 0x40f3de1650000000 */
924afb647cSTimo Kreuzer     2.21206695312500000000e+05,  /* 0x410b00b590000000 */
934afb647cSTimo Kreuzer     6.01302140625000000000e+05,  /* 0x412259ac48000000 */
944afb647cSTimo Kreuzer     1.63450865625000000000e+06,  /* 0x4138f0cca8000000 */
954afb647cSTimo Kreuzer     4.44305525000000000000e+06,  /* 0x4150f2ebd0000000 */
964afb647cSTimo Kreuzer     1.20774762500000000000e+07,  /* 0x4167093488000000 */
974afb647cSTimo Kreuzer     3.28299845000000000000e+07,  /* 0x417f4f2208000000 */
984afb647cSTimo Kreuzer     8.92411500000000000000e+07,  /* 0x419546d8f8000000 */
994afb647cSTimo Kreuzer     2.42582596000000000000e+08,  /* 0x41aceb0888000000 */
1004afb647cSTimo Kreuzer     6.59407856000000000000e+08,  /* 0x41c3a6e1f8000000 */
1014afb647cSTimo Kreuzer     1.79245641600000000000e+09,  /* 0x41dab5adb8000000 */
1024afb647cSTimo Kreuzer     4.87240166400000000000e+09,  /* 0x41f226af30000000 */
1034afb647cSTimo Kreuzer     1.32445608960000000000e+10,  /* 0x4208ab7fb0000000 */
1044afb647cSTimo Kreuzer     3.60024494080000000000e+10,  /* 0x4220c3d390000000 */
1054afb647cSTimo Kreuzer     9.78648043520000000000e+10,  /* 0x4236c93268000000 */
1064afb647cSTimo Kreuzer     2.66024116224000000000e+11,  /* 0x424ef822f0000000 */
1074afb647cSTimo Kreuzer     7.23128516608000000000e+11,  /* 0x42650bba30000000 */
1084afb647cSTimo Kreuzer     1.96566712320000000000e+12,  /* 0x427c9aae40000000 */
1094afb647cSTimo Kreuzer     5.34323724288000000000e+12,  /* 0x4293704708000000 */
1104afb647cSTimo Kreuzer     1.45244246507520000000e+13,  /* 0x42aa6b7658000000 */
1114afb647cSTimo Kreuzer     3.94814795284480000000e+13,  /* 0x42c1f43fc8000000 */
1124afb647cSTimo Kreuzer     1.07321789251584000000e+14,  /* 0x42d866f348000000 */
1134afb647cSTimo Kreuzer     2.91730863685632000000e+14,  /* 0x42f0953e28000000 */
1144afb647cSTimo Kreuzer     7.93006722514944000000e+14,  /* 0x430689e220000000 */
1154afb647cSTimo Kreuzer     2.15561576592179200000e+15}; /* 0x431ea215a0000000 */
1164afb647cSTimo Kreuzer 
1174afb647cSTimo Kreuzer   static const double sinh_tail[37] = {
1184afb647cSTimo Kreuzer     0.00000000000000000000e+00,  /* 0x0000000000000000 */
1194afb647cSTimo Kreuzer     1.60467555584448807892e-08,  /* 0x3e513ae6096a0092 */
1204afb647cSTimo Kreuzer     2.76742892754807136947e-08,  /* 0x3e5db70cfb79a640 */
1214afb647cSTimo Kreuzer     2.09697499555224576530e-07,  /* 0x3e8c2526b66dc067 */
1224afb647cSTimo Kreuzer     2.04940252448908240062e-07,  /* 0x3e8b81b18647f380 */
1234afb647cSTimo Kreuzer     1.65444891522700935932e-06,  /* 0x3ebbc1cdd1e1eb08 */
1244afb647cSTimo Kreuzer     3.53116789999998198721e-06,  /* 0x3ecd9f201534fb09 */
1254afb647cSTimo Kreuzer     6.94023870987375490695e-06,  /* 0x3edd1c064a4e9954 */
1264afb647cSTimo Kreuzer     4.98876893611587449271e-06,  /* 0x3ed4eca65d06ea74 */
1274afb647cSTimo Kreuzer     3.19656024605152215752e-05,  /* 0x3f00c259bcc0ecc5 */
1284afb647cSTimo Kreuzer     2.08687768377236501204e-04,  /* 0x3f2b5a6647cf9016 */
1294afb647cSTimo Kreuzer     4.84668088325403796299e-05,  /* 0x3f09691adefb0870 */
1304afb647cSTimo Kreuzer     1.17517985422733832468e-03,  /* 0x3f53410fc29cde38 */
1314afb647cSTimo Kreuzer     6.90830086959560562415e-04,  /* 0x3f46a31a50b6fb3c */
1324afb647cSTimo Kreuzer     1.45697262451506548420e-03,  /* 0x3f57defc71805c40 */
1334afb647cSTimo Kreuzer     2.99859023684906737806e-02,  /* 0x3f9eb49fd80e0bab */
1344afb647cSTimo Kreuzer     1.02538800507941396667e-02,  /* 0x3f84fffc7bcd5920 */
1354afb647cSTimo Kreuzer     1.26787628407699110022e-01,  /* 0x3fc03a93b6c63435 */
1364afb647cSTimo Kreuzer     6.86652479544033744752e-02,  /* 0x3fb1940bb255fd1c */
1374afb647cSTimo Kreuzer     4.81593627621056619148e-01,  /* 0x3fded26e14260b50 */
1384afb647cSTimo Kreuzer     1.70489513795397629181e+00,  /* 0x3ffb47401fc9f2a2 */
1394afb647cSTimo Kreuzer     1.12416073482258713767e+01,  /* 0x40267bb3f55634f1 */
1404afb647cSTimo Kreuzer     7.06579578070110514432e+00,  /* 0x401c435ff8194ddc */
1414afb647cSTimo Kreuzer     5.91244512999659974639e+01,  /* 0x404d8fee052ba63a */
1424afb647cSTimo Kreuzer     1.68921736147050694399e+02,  /* 0x40651d7edccde3f6 */
1434afb647cSTimo Kreuzer     2.60692936262073658327e+02,  /* 0x40704b1644557d1a */
1444afb647cSTimo Kreuzer     3.62419382134885609048e+02,  /* 0x4076a6b5ca0a9dc4 */
1454afb647cSTimo Kreuzer     4.07689930834187271103e+03,  /* 0x40afd9cc72249aba */
1464afb647cSTimo Kreuzer     1.55377375868385224749e+04,  /* 0x40ce58de693edab5 */
1474afb647cSTimo Kreuzer     2.53720210371943067003e+04,  /* 0x40d8c70158ac6363 */
1484afb647cSTimo Kreuzer     4.78822310734952334315e+04,  /* 0x40e7614764f43e20 */
1494afb647cSTimo Kreuzer     1.81871712615542812273e+05,  /* 0x4106337db36fc718 */
1504afb647cSTimo Kreuzer     5.62892347580489004031e+05,  /* 0x41212d98b1f611e2 */
1514afb647cSTimo Kreuzer     6.41374032312148716301e+05,  /* 0x412392bc108b37cc */
1524afb647cSTimo Kreuzer     7.57809544070145115256e+06,  /* 0x415ce87bdc3473dc */
1534afb647cSTimo Kreuzer     3.64177136406482197344e+06,  /* 0x414bc8d5ae99ad14 */
1544afb647cSTimo Kreuzer     7.63580561355670914054e+06}; /* 0x415d20d76744835c */
1554afb647cSTimo Kreuzer 
1564afb647cSTimo Kreuzer   static const double cosh_lead[37] = {
1574afb647cSTimo Kreuzer     1.00000000000000000000e+00,  /* 0x3ff0000000000000 */
1584afb647cSTimo Kreuzer     1.54308062791824340820e+00,  /* 0x3ff8b07550000000 */
1594afb647cSTimo Kreuzer     3.76219564676284790039e+00,  /* 0x400e18fa08000000 */
1604afb647cSTimo Kreuzer     1.00676617622375488281e+01,  /* 0x402422a490000000 */
1614afb647cSTimo Kreuzer     2.73082327842712402344e+01,  /* 0x403b4ee858000000 */
1624afb647cSTimo Kreuzer     7.42099475860595703125e+01,  /* 0x40528d6fc8000000 */
1634afb647cSTimo Kreuzer     2.01715633392333984375e+02,  /* 0x406936e678000000 */
1644afb647cSTimo Kreuzer     5.48317031860351562500e+02,  /* 0x4081228948000000 */
1654afb647cSTimo Kreuzer     1.49047915649414062500e+03,  /* 0x409749eaa8000000 */
1664afb647cSTimo Kreuzer     4.05154199218750000000e+03,  /* 0x40afa71580000000 */
1674afb647cSTimo Kreuzer     1.10132329101562500000e+04,  /* 0x40c5829dd0000000 */
1684afb647cSTimo Kreuzer     2.99370708007812500000e+04,  /* 0x40dd3c4488000000 */
1694afb647cSTimo Kreuzer     8.13773945312500000000e+04,  /* 0x40f3de1650000000 */
1704afb647cSTimo Kreuzer     2.21206695312500000000e+05,  /* 0x410b00b590000000 */
1714afb647cSTimo Kreuzer     6.01302140625000000000e+05,  /* 0x412259ac48000000 */
1724afb647cSTimo Kreuzer     1.63450865625000000000e+06,  /* 0x4138f0cca8000000 */
1734afb647cSTimo Kreuzer     4.44305525000000000000e+06,  /* 0x4150f2ebd0000000 */
1744afb647cSTimo Kreuzer     1.20774762500000000000e+07,  /* 0x4167093488000000 */
1754afb647cSTimo Kreuzer     3.28299845000000000000e+07,  /* 0x417f4f2208000000 */
1764afb647cSTimo Kreuzer     8.92411500000000000000e+07,  /* 0x419546d8f8000000 */
1774afb647cSTimo Kreuzer     2.42582596000000000000e+08,  /* 0x41aceb0888000000 */
1784afb647cSTimo Kreuzer     6.59407856000000000000e+08,  /* 0x41c3a6e1f8000000 */
1794afb647cSTimo Kreuzer     1.79245641600000000000e+09,  /* 0x41dab5adb8000000 */
1804afb647cSTimo Kreuzer     4.87240166400000000000e+09,  /* 0x41f226af30000000 */
1814afb647cSTimo Kreuzer     1.32445608960000000000e+10,  /* 0x4208ab7fb0000000 */
1824afb647cSTimo Kreuzer     3.60024494080000000000e+10,  /* 0x4220c3d390000000 */
1834afb647cSTimo Kreuzer     9.78648043520000000000e+10,  /* 0x4236c93268000000 */
1844afb647cSTimo Kreuzer     2.66024116224000000000e+11,  /* 0x424ef822f0000000 */
1854afb647cSTimo Kreuzer     7.23128516608000000000e+11,  /* 0x42650bba30000000 */
1864afb647cSTimo Kreuzer     1.96566712320000000000e+12,  /* 0x427c9aae40000000 */
1874afb647cSTimo Kreuzer     5.34323724288000000000e+12,  /* 0x4293704708000000 */
1884afb647cSTimo Kreuzer     1.45244246507520000000e+13,  /* 0x42aa6b7658000000 */
1894afb647cSTimo Kreuzer     3.94814795284480000000e+13,  /* 0x42c1f43fc8000000 */
1904afb647cSTimo Kreuzer     1.07321789251584000000e+14,  /* 0x42d866f348000000 */
1914afb647cSTimo Kreuzer     2.91730863685632000000e+14,  /* 0x42f0953e28000000 */
1924afb647cSTimo Kreuzer     7.93006722514944000000e+14,  /* 0x430689e220000000 */
1934afb647cSTimo Kreuzer     2.15561576592179200000e+15}; /* 0x431ea215a0000000 */
1944afb647cSTimo Kreuzer 
1954afb647cSTimo Kreuzer   static const double cosh_tail[37] = {
1964afb647cSTimo Kreuzer     0.00000000000000000000e+00,  /* 0x0000000000000000 */
1974afb647cSTimo Kreuzer     6.89700037027478056904e-09,  /* 0x3e3d9f5504c2bd28 */
1984afb647cSTimo Kreuzer     4.43207835591715833630e-08,  /* 0x3e67cb66f0a4c9fd */
1994afb647cSTimo Kreuzer     2.33540217013828929694e-07,  /* 0x3e8f58617928e588 */
2004afb647cSTimo Kreuzer     5.17452463948269748331e-08,  /* 0x3e6bc7d000c38d48 */
2014afb647cSTimo Kreuzer     9.38728274131605919153e-07,  /* 0x3eaf7f9d4e329998 */
2024afb647cSTimo Kreuzer     2.73012191010840495544e-06,  /* 0x3ec6e6e464885269 */
2034afb647cSTimo Kreuzer     3.29486051438996307950e-06,  /* 0x3ecba3a8b946c154 */
2044afb647cSTimo Kreuzer     4.75803746362771416375e-06,  /* 0x3ed3f4e76110d5a4 */
2054afb647cSTimo Kreuzer     3.33050940471947692369e-05,  /* 0x3f017622515a3e2b */
2064afb647cSTimo Kreuzer     9.94707313972136215365e-06,  /* 0x3ee4dc4b528af3d0 */
2074afb647cSTimo Kreuzer     6.51685096227860253398e-05,  /* 0x3f11156278615e10 */
2084afb647cSTimo Kreuzer     1.18132406658066663359e-03,  /* 0x3f535ad50ed821f5 */
2094afb647cSTimo Kreuzer     6.93090416366541877541e-04,  /* 0x3f46b61055f2935c */
2104afb647cSTimo Kreuzer     1.45780415323416845386e-03,  /* 0x3f57e2794a601240 */
2114afb647cSTimo Kreuzer     2.99862082708111758744e-02,  /* 0x3f9eb4b45f6aadd3 */
2124afb647cSTimo Kreuzer     1.02539925859688602072e-02,  /* 0x3f85000b967b3698 */
2134afb647cSTimo Kreuzer     1.26787669807076286421e-01,  /* 0x3fc03a940fadc092 */
2144afb647cSTimo Kreuzer     6.86652631843830962843e-02,  /* 0x3fb1940bf3bf874c */
2154afb647cSTimo Kreuzer     4.81593633223853068159e-01,  /* 0x3fded26e1a2a2110 */
2164afb647cSTimo Kreuzer     1.70489514001513020602e+00,  /* 0x3ffb4740205796d6 */
2174afb647cSTimo Kreuzer     1.12416073489841270572e+01,  /* 0x40267bb3f55cb85d */
2184afb647cSTimo Kreuzer     7.06579578098005001152e+00,  /* 0x401c435ff81e18ac */
2194afb647cSTimo Kreuzer     5.91244513000686140458e+01,  /* 0x404d8fee052bdea4 */
2204afb647cSTimo Kreuzer     1.68921736147088438429e+02,  /* 0x40651d7edccde926 */
2214afb647cSTimo Kreuzer     2.60692936262087528121e+02,  /* 0x40704b1644557e0e */
2224afb647cSTimo Kreuzer     3.62419382134890611269e+02,  /* 0x4076a6b5ca0a9e1c */
2234afb647cSTimo Kreuzer     4.07689930834187453002e+03,  /* 0x40afd9cc72249abe */
2244afb647cSTimo Kreuzer     1.55377375868385224749e+04,  /* 0x40ce58de693edab5 */
2254afb647cSTimo Kreuzer     2.53720210371943103382e+04,  /* 0x40d8c70158ac6364 */
2264afb647cSTimo Kreuzer     4.78822310734952334315e+04,  /* 0x40e7614764f43e20 */
2274afb647cSTimo Kreuzer     1.81871712615542812273e+05,  /* 0x4106337db36fc718 */
2284afb647cSTimo Kreuzer     5.62892347580489004031e+05,  /* 0x41212d98b1f611e2 */
2294afb647cSTimo Kreuzer     6.41374032312148716301e+05,  /* 0x412392bc108b37cc */
2304afb647cSTimo Kreuzer     7.57809544070145115256e+06,  /* 0x415ce87bdc3473dc */
2314afb647cSTimo Kreuzer     3.64177136406482197344e+06,  /* 0x414bc8d5ae99ad14 */
2324afb647cSTimo Kreuzer     7.63580561355670914054e+06}; /* 0x415d20d76744835c */
2334afb647cSTimo Kreuzer 
234*9e8ed3f8STimo Kreuzer   unsigned long long ux, aux, xneg;
2354afb647cSTimo Kreuzer   double y, z, z1, z2;
2364afb647cSTimo Kreuzer   int m;
2374afb647cSTimo Kreuzer 
2384afb647cSTimo Kreuzer   /* Special cases */
2394afb647cSTimo Kreuzer 
2404afb647cSTimo Kreuzer   GET_BITS_DP64(x, ux);
2414afb647cSTimo Kreuzer   aux = ux & ~SIGNBIT_DP64;
2424afb647cSTimo Kreuzer   if (aux < 0x3e30000000000000) /* |x| small enough that sinh(x) = x */
2434afb647cSTimo Kreuzer     {
2444afb647cSTimo Kreuzer       if (aux == 0)
2454afb647cSTimo Kreuzer         /* with no inexact */
2464afb647cSTimo Kreuzer         return x;
2474afb647cSTimo Kreuzer       else
2484afb647cSTimo Kreuzer         return val_with_flags(x, AMD_F_INEXACT);
2494afb647cSTimo Kreuzer     }
2504afb647cSTimo Kreuzer   else if (aux >= 0x7ff0000000000000) /* |x| is NaN or Inf */
2514afb647cSTimo Kreuzer     {
2524afb647cSTimo Kreuzer       if (aux > 0x7ff0000000000000)
2534afb647cSTimo Kreuzer         /* x is NaN */
2544afb647cSTimo Kreuzer         return _handle_error("sinh", OP_SINH, ux|0x0008000000000000, _DOMAIN,
2554afb647cSTimo Kreuzer                             0, EDOM, x, 0.0, 1);
2564afb647cSTimo Kreuzer       else
2574afb647cSTimo Kreuzer       return x + x;
2584afb647cSTimo Kreuzer     }
2594afb647cSTimo Kreuzer 
2604afb647cSTimo Kreuzer 
2614afb647cSTimo Kreuzer   xneg = (aux != ux);
2624afb647cSTimo Kreuzer 
2634afb647cSTimo Kreuzer   y = x;
2644afb647cSTimo Kreuzer   if (xneg) y = -x;
2654afb647cSTimo Kreuzer 
2664afb647cSTimo Kreuzer   if (y >= max_sinh_arg)
2674afb647cSTimo Kreuzer     {
2684afb647cSTimo Kreuzer       if (xneg)
2694afb647cSTimo Kreuzer         return _handle_error("sinh", OP_SINH, NINFBITPATT_DP64, _OVERFLOW,
2704afb647cSTimo Kreuzer                             AMD_F_OVERFLOW, ERANGE, x, 0.0, 1);
2714afb647cSTimo Kreuzer       else
2724afb647cSTimo Kreuzer         return _handle_error("sinh", OP_SINH, PINFBITPATT_DP64, _OVERFLOW,
2734afb647cSTimo Kreuzer                             AMD_F_OVERFLOW, ERANGE, x, 0.0, 1);
2744afb647cSTimo Kreuzer     }
2754afb647cSTimo Kreuzer   else if (y >= small_threshold)
2764afb647cSTimo Kreuzer     {
2774afb647cSTimo Kreuzer       /* In this range y is large enough so that
2784afb647cSTimo Kreuzer          the negative exponential is negligible,
2794afb647cSTimo Kreuzer          so sinh(y) is approximated by sign(x)*exp(y)/2. The
2804afb647cSTimo Kreuzer          code below is an inlined version of that from
2814afb647cSTimo Kreuzer          exp() with two changes (it operates on
2824afb647cSTimo Kreuzer          y instead of x, and the division by 2 is
2834afb647cSTimo Kreuzer          done by reducing m by 1). */
2844afb647cSTimo Kreuzer 
2854afb647cSTimo Kreuzer       splitexp(y, 1.0, thirtytwo_by_log2, log2_by_32_lead,
2864afb647cSTimo Kreuzer                log2_by_32_tail, &m, &z1, &z2);
2874afb647cSTimo Kreuzer       m -= 1;
2884afb647cSTimo Kreuzer 
2894afb647cSTimo Kreuzer       if (m >= EMIN_DP64 && m <= EMAX_DP64)
2904afb647cSTimo Kreuzer         z = scaleDouble_1((z1+z2),m);
2914afb647cSTimo Kreuzer       else
2924afb647cSTimo Kreuzer         z = scaleDouble_2((z1+z2),m);
2934afb647cSTimo Kreuzer     }
2944afb647cSTimo Kreuzer   else
2954afb647cSTimo Kreuzer     {
2964afb647cSTimo Kreuzer       /* In this range we find the integer part y0 of y
2974afb647cSTimo Kreuzer          and the increment dy = y - y0. We then compute
2984afb647cSTimo Kreuzer 
2994afb647cSTimo Kreuzer          z = sinh(y) = sinh(y0)cosh(dy) + cosh(y0)sinh(dy)
3004afb647cSTimo Kreuzer 
3014afb647cSTimo Kreuzer          where sinh(y0) and cosh(y0) are tabulated above. */
3024afb647cSTimo Kreuzer 
3034afb647cSTimo Kreuzer       int ind;
3044afb647cSTimo Kreuzer       double dy, dy2, sdy, cdy, sdy1, sdy2;
3054afb647cSTimo Kreuzer 
3064afb647cSTimo Kreuzer       ind = (int)y;
3074afb647cSTimo Kreuzer       dy = y - ind;
3084afb647cSTimo Kreuzer 
3094afb647cSTimo Kreuzer       dy2 = dy*dy;
3104afb647cSTimo Kreuzer       sdy = dy*dy2*(0.166666666666666667013899e0 +
3114afb647cSTimo Kreuzer                     (0.833333333333329931873097e-2 +
3124afb647cSTimo Kreuzer                      (0.198412698413242405162014e-3 +
3134afb647cSTimo Kreuzer                       (0.275573191913636406057211e-5 +
3144afb647cSTimo Kreuzer                        (0.250521176994133472333666e-7 +
3154afb647cSTimo Kreuzer                         (0.160576793121939886190847e-9 +
3164afb647cSTimo Kreuzer                          0.7746188980094184251527126e-12*dy2)*dy2)*dy2)*dy2)*dy2)*dy2);
3174afb647cSTimo Kreuzer 
3184afb647cSTimo Kreuzer       cdy = dy2*(0.500000000000000005911074e0 +
3194afb647cSTimo Kreuzer                  (0.416666666666660876512776e-1 +
3204afb647cSTimo Kreuzer                   (0.138888888889814854814536e-2 +
3214afb647cSTimo Kreuzer                    (0.248015872460622433115785e-4 +
3224afb647cSTimo Kreuzer                     (0.275573350756016588011357e-6 +
3234afb647cSTimo Kreuzer                      (0.208744349831471353536305e-8 +
3244afb647cSTimo Kreuzer                       0.1163921388172173692062032e-10*dy2)*dy2)*dy2)*dy2)*dy2)*dy2);
3254afb647cSTimo Kreuzer 
3264afb647cSTimo Kreuzer       /* At this point sinh(dy) is approximated by dy + sdy.
3274afb647cSTimo Kreuzer 	 Shift some significant bits from dy to sdy. */
3284afb647cSTimo Kreuzer 
3294afb647cSTimo Kreuzer       GET_BITS_DP64(dy, ux);
3304afb647cSTimo Kreuzer       ux &= 0xfffffffff8000000;
3314afb647cSTimo Kreuzer       PUT_BITS_DP64(ux, sdy1);
3324afb647cSTimo Kreuzer       sdy2 = sdy + (dy - sdy1);
3334afb647cSTimo Kreuzer 
3344afb647cSTimo Kreuzer       z = ((((((cosh_tail[ind]*sdy2 + sinh_tail[ind]*cdy)
3354afb647cSTimo Kreuzer 	       + cosh_tail[ind]*sdy1) + sinh_tail[ind])
3364afb647cSTimo Kreuzer 	     + cosh_lead[ind]*sdy2) + sinh_lead[ind]*cdy)
3374afb647cSTimo Kreuzer 	   + cosh_lead[ind]*sdy1) + sinh_lead[ind];
3384afb647cSTimo Kreuzer     }
3394afb647cSTimo Kreuzer 
3404afb647cSTimo Kreuzer   if (xneg) z = - z;
3414afb647cSTimo Kreuzer   return z;
3424afb647cSTimo Kreuzer }
343