1130803Smarcel#define _GNU_SOURCE
2130803Smarcel#include "libm.h"
3130803Smarcel
4130803Smarcel#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
5130803Smarcelvoid sincosl(long double x, long double *sin, long double *cos)
6130803Smarcel{
7130803Smarcel	double sind, cosd;
8130803Smarcel	sincos(x, &sind, &cosd);
9130803Smarcel	*sin = sind;
10130803Smarcel	*cos = cosd;
11130803Smarcel}
12130803Smarcel#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
13130803Smarcelvoid sincosl(long double x, long double *sin, long double *cos)
14130803Smarcel{
15130803Smarcel	union ldshape u = {x};
16130803Smarcel	unsigned n;
17130803Smarcel	long double y[2], s, c;
18130803Smarcel
19130803Smarcel	u.i.se &= 0x7fff;
20130803Smarcel	if (u.i.se == 0x7fff) {
21130803Smarcel		*sin = *cos = x - x;
22130803Smarcel		return;
23130803Smarcel	}
24130803Smarcel	if (u.f < M_PI_4) {
25130803Smarcel		if (u.i.se < 0x3fff - LDBL_MANT_DIG) {
26130803Smarcel			/* raise underflow if subnormal */
27130803Smarcel			if (u.i.se == 0) FORCE_EVAL(x*0x1p-120f);
28130803Smarcel			*sin = x;
29130803Smarcel			/* raise inexact if x!=0 */
30130803Smarcel			*cos = 1.0 + x;
31130803Smarcel			return;
32130803Smarcel		}
33130803Smarcel		*sin = __sinl(x, 0, 0);
34130803Smarcel		*cos = __cosl(x, 0);
35130803Smarcel		return;
36130803Smarcel	}
37130803Smarcel	n = __rem_pio2l(x, y);
38130803Smarcel	s = __sinl(y[0], y[1], 1);
39130803Smarcel	c = __cosl(y[0], y[1]);
40130803Smarcel	switch (n & 3) {
41130803Smarcel	case 0:
42130803Smarcel		*sin = s;
43130803Smarcel		*cos = c;
44130803Smarcel		break;
45130803Smarcel	case 1:
46130803Smarcel		*sin = c;
47130803Smarcel		*cos = -s;
48130803Smarcel		break;
49130803Smarcel	case 2:
50130803Smarcel		*sin = -s;
51130803Smarcel		*cos = -c;
52130803Smarcel		break;
53130803Smarcel	case 3:
54130803Smarcel	default:
55130803Smarcel		*sin = -c;
56130803Smarcel		*cos = s;
57130803Smarcel		break;
58130803Smarcel	}
59130803Smarcel}
60130803Smarcel#endif
61130803Smarcel