1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double sinhl(long double x) {
5    return sinh(x);
6}
7#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
8long double sinhl(long double x) {
9    union ldshape u = {x};
10    unsigned ex = u.i.se & 0x7fff;
11    long double h, t, absx;
12
13    h = 0.5;
14    if (u.i.se & 0x8000)
15        h = -h;
16    /* |x| */
17    u.i.se = ex;
18    absx = u.f;
19
20    /* |x| < log(LDBL_MAX) */
21    if (ex < 0x3fff + 13 || (ex == 0x3fff + 13 && u.i.m >> 32 < 0xb17217f7)) {
22        t = expm1l(absx);
23        if (ex < 0x3fff) {
24            if (ex < 0x3fff - 32)
25                return x;
26            return h * (2 * t - t * t / (1 + t));
27        }
28        return h * (t + t / (t + 1));
29    }
30
31    /* |x| > log(LDBL_MAX) or nan */
32    t = expl(0.5 * absx);
33    return h * t * t;
34}
35#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
36// TODO: broken implementation to make things compile
37long double sinhl(long double x) {
38    return sinh(x);
39}
40#endif
41