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