1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double nextafterl(long double x, long double y) {
5    return nextafter(x, y);
6}
7#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
8long double nextafterl(long double x, long double y) {
9    union ldshape ux, uy;
10
11    if (isnan(x) || isnan(y))
12        return x + y;
13    if (x == y)
14        return y;
15    ux.f = x;
16    if (x == 0) {
17        uy.f = y;
18        ux.i.m = 1;
19        ux.i.se = uy.i.se & 0x8000;
20    } else if ((x < y) == !(ux.i.se & 0x8000)) {
21        ux.i.m++;
22        if (ux.i.m << 1 == 0) {
23            ux.i.m = 1ULL << 63;
24            ux.i.se++;
25        }
26    } else {
27        if (ux.i.m << 1 == 0) {
28            ux.i.se--;
29            if (ux.i.se)
30                ux.i.m = 0;
31        }
32        ux.i.m--;
33    }
34    /* raise overflow if ux is infinite and x is finite */
35    if ((ux.i.se & 0x7fff) == 0x7fff)
36        return x + x;
37    /* raise underflow if ux is subnormal or zero */
38    if ((ux.i.se & 0x7fff) == 0)
39        FORCE_EVAL(x * x + ux.f * ux.f);
40    return ux.f;
41}
42#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
43long double nextafterl(long double x, long double y) {
44    union ldshape ux, uy;
45
46    if (isnan(x) || isnan(y))
47        return x + y;
48    if (x == y)
49        return y;
50    ux.f = x;
51    if (x == 0) {
52        uy.f = y;
53        ux.i.lo = 1;
54        ux.i.se = uy.i.se & 0x8000;
55    } else if ((x < y) == !(ux.i.se & 0x8000)) {
56        ux.i2.lo++;
57        if (ux.i2.lo == 0)
58            ux.i2.hi++;
59    } else {
60        if (ux.i2.lo == 0)
61            ux.i2.hi--;
62        ux.i2.lo--;
63    }
64    /* raise overflow if ux is infinite and x is finite */
65    if ((ux.i.se & 0x7fff) == 0x7fff)
66        return x + x;
67    /* raise underflow if ux is subnormal or zero */
68    if ((ux.i.se & 0x7fff) == 0)
69        FORCE_EVAL(x * x + ux.f * ux.f);
70    return ux.f;
71}
72#endif
73