1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double tanhl(long double x)
5{
6	return tanh(x);
7}
8#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
9long double tanhl(long double x)
10{
11	union ldshape u = {x};
12	unsigned ex = u.i.se & 0x7fff;
13	unsigned sign = u.i.se & 0x8000;
14	uint32_t w;
15	long double t;
16
17	/* x = |x| */
18	u.i.se = ex;
19	x = u.f;
20	w = u.i.m >> 32;
21
22	if (ex > 0x3ffe || (ex == 0x3ffe && w > 0x8c9f53d5)) {
23		/* |x| > log(3)/2 ~= 0.5493 or nan */
24		if (ex >= 0x3fff+5) {
25			/* |x| >= 32 */
26			t = 1 + 0/(x + 0x1p-120f);
27		} else {
28			t = expm1l(2*x);
29			t = 1 - 2/(t+2);
30		}
31	} else if (ex > 0x3ffd || (ex == 0x3ffd && w > 0x82c577d4)) {
32		/* |x| > log(5/3)/2 ~= 0.2554 */
33		t = expm1l(2*x);
34		t = t/(t+2);
35	} else {
36		/* |x| is small */
37		t = expm1l(-2*x);
38		t = -t/(t+2);
39	}
40	return sign ? -t : t;
41}
42#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
43// TODO: broken implementation to make things compile
44long double tanhl(long double x)
45{
46	return tanh(x);
47}
48#endif
49