1#include "libm.h"
2#include <limits.h>
3
4#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
5int ilogbl(long double x) {
6    return ilogb(x);
7}
8#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
9int ilogbl(long double x) {
10    PRAGMA_STDC_FENV_ACCESS_ON
11    union ldshape u = {x};
12    uint64_t m = u.i.m;
13    int e = u.i.se & 0x7fff;
14
15    if (!e) {
16        if (m == 0) {
17            FORCE_EVAL(0 / 0.0f);
18            return FP_ILOGB0;
19        }
20        /* subnormal x */
21        for (e = -0x3fff + 1; m >> 63 == 0; e--, m <<= 1)
22            ;
23        return e;
24    }
25    if (e == 0x7fff) {
26        FORCE_EVAL(0 / 0.0f);
27        return m << 1 ? FP_ILOGBNAN : INT_MAX;
28    }
29    return e - 0x3fff;
30}
31#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
32int ilogbl(long double x) {
33    PRAGMA_STDC_FENV_ACCESS_ON
34    union ldshape u = {x};
35    int e = u.i.se & 0x7fff;
36
37    if (!e) {
38        if (x == 0) {
39            FORCE_EVAL(0 / 0.0f);
40            return FP_ILOGB0;
41        }
42        /* subnormal x */
43        x *= 0x1p120;
44        return ilogbl(x) - 120;
45    }
46    if (e == 0x7fff) {
47        FORCE_EVAL(0 / 0.0f);
48        u.i.se = 0;
49        return u.f ? FP_ILOGBNAN : INT_MAX;
50    }
51    return e - 0x3fff;
52}
53#endif
54