xref: /freebsd/contrib/arm-optimized-routines/pl/math/trigpi_references.c (revision 5ca8e32633c4ffbbcd6762e5888b6a4ba0708c6c)
1 /*
2  * Extended precision scalar reference functions for trigpi.
3  *
4  * Copyright (c) 2023, Arm Limited.
5  * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
6  */
7 
8 #define _GNU_SOURCE
9 #include "math_config.h"
10 #include "mathlib.h"
11 
12 long double
13 sinpil (long double x)
14 {
15   /* sin(inf) should return nan, as defined by C23.  */
16   if (isinf (x))
17     return __math_invalid (x);
18 
19   long double ax = fabsl (x);
20 
21   /* Return 0 for all values above 2^64 to prevent
22      overflow when casting to uint64_t.  */
23   if (ax >= 0x1p64)
24     return 0;
25 
26   /* All integer cases should return 0.  */
27   if (ax == (uint64_t) ax)
28     return 0;
29 
30   return sinl (x * M_PIl);
31 }
32 
33 long double
34 cospil (long double x)
35 {
36   /* cos(inf) should return nan, as defined by C23.  */
37   if (isinf (x))
38     return __math_invalid (x);
39 
40   long double ax = fabsl (x);
41 
42   if (ax >= 0x1p64)
43     return 1;
44 
45   uint64_t m = (uint64_t) ax;
46 
47   /* Integer values of cospi(x) should return +/-1.
48     The sign depends on if x is odd or even.  */
49   if (m == ax)
50     return (m & 1) ? -1 : 1;
51 
52   /* Values of Integer + 0.5 should always return 0.  */
53   if (ax - 0.5 == m || ax + 0.5 == m)
54     return 0;
55 
56   return cosl (ax * M_PIl);
57 }