1570af302Sopenharmony_ci#include "libm.h"
2570af302Sopenharmony_ci
3570af302Sopenharmony_ci#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4570af302Sopenharmony_cilong double nextafterl(long double x, long double y)
5570af302Sopenharmony_ci{
6570af302Sopenharmony_ci	return nextafter(x, y);
7570af302Sopenharmony_ci}
8570af302Sopenharmony_ci#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
9570af302Sopenharmony_cilong double nextafterl(long double x, long double y)
10570af302Sopenharmony_ci{
11570af302Sopenharmony_ci	union ldshape ux, uy;
12570af302Sopenharmony_ci
13570af302Sopenharmony_ci	if (isnan(x) || isnan(y))
14570af302Sopenharmony_ci		return x + y;
15570af302Sopenharmony_ci	if (x == y)
16570af302Sopenharmony_ci		return y;
17570af302Sopenharmony_ci	ux.f = x;
18570af302Sopenharmony_ci	if (x == 0) {
19570af302Sopenharmony_ci		uy.f = y;
20570af302Sopenharmony_ci		ux.i.m = 1;
21570af302Sopenharmony_ci		ux.i.se = uy.i.se & 0x8000;
22570af302Sopenharmony_ci	} else if ((x < y) == !(ux.i.se & 0x8000)) {
23570af302Sopenharmony_ci		ux.i.m++;
24570af302Sopenharmony_ci		if (ux.i.m << 1 == 0) {
25570af302Sopenharmony_ci			ux.i.m = 1ULL << 63;
26570af302Sopenharmony_ci			ux.i.se++;
27570af302Sopenharmony_ci		}
28570af302Sopenharmony_ci	} else {
29570af302Sopenharmony_ci		if (ux.i.m << 1 == 0) {
30570af302Sopenharmony_ci			ux.i.se--;
31570af302Sopenharmony_ci			if (ux.i.se)
32570af302Sopenharmony_ci				ux.i.m = 0;
33570af302Sopenharmony_ci		}
34570af302Sopenharmony_ci		ux.i.m--;
35570af302Sopenharmony_ci	}
36570af302Sopenharmony_ci	/* raise overflow if ux is infinite and x is finite */
37570af302Sopenharmony_ci	if ((ux.i.se & 0x7fff) == 0x7fff)
38570af302Sopenharmony_ci		return x + x;
39570af302Sopenharmony_ci	/* raise underflow if ux is subnormal or zero */
40570af302Sopenharmony_ci	if ((ux.i.se & 0x7fff) == 0)
41570af302Sopenharmony_ci		FORCE_EVAL(x*x + ux.f*ux.f);
42570af302Sopenharmony_ci	return ux.f;
43570af302Sopenharmony_ci}
44570af302Sopenharmony_ci#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
45570af302Sopenharmony_cilong double nextafterl(long double x, long double y)
46570af302Sopenharmony_ci{
47570af302Sopenharmony_ci	union ldshape ux, uy;
48570af302Sopenharmony_ci
49570af302Sopenharmony_ci	if (isnan(x) || isnan(y))
50570af302Sopenharmony_ci		return x + y;
51570af302Sopenharmony_ci	if (x == y)
52570af302Sopenharmony_ci		return y;
53570af302Sopenharmony_ci	ux.f = x;
54570af302Sopenharmony_ci	if (x == 0) {
55570af302Sopenharmony_ci		uy.f = y;
56570af302Sopenharmony_ci		ux.i.lo = 1;
57570af302Sopenharmony_ci		ux.i.se = uy.i.se & 0x8000;
58570af302Sopenharmony_ci	} else if ((x < y) == !(ux.i.se & 0x8000)) {
59570af302Sopenharmony_ci		ux.i2.lo++;
60570af302Sopenharmony_ci		if (ux.i2.lo == 0)
61570af302Sopenharmony_ci			ux.i2.hi++;
62570af302Sopenharmony_ci	} else {
63570af302Sopenharmony_ci		if (ux.i2.lo == 0)
64570af302Sopenharmony_ci			ux.i2.hi--;
65570af302Sopenharmony_ci		ux.i2.lo--;
66570af302Sopenharmony_ci	}
67570af302Sopenharmony_ci	/* raise overflow if ux is infinite and x is finite */
68570af302Sopenharmony_ci	if ((ux.i.se & 0x7fff) == 0x7fff)
69570af302Sopenharmony_ci		return x + x;
70570af302Sopenharmony_ci	/* raise underflow if ux is subnormal or zero */
71570af302Sopenharmony_ci	if ((ux.i.se & 0x7fff) == 0)
72570af302Sopenharmony_ci		FORCE_EVAL(x*x + ux.f*ux.f);
73570af302Sopenharmony_ci	return ux.f;
74570af302Sopenharmony_ci}
75570af302Sopenharmony_ci#endif
76