Fraser Cormack 13a313fe58
[libclc] Move sinpi/cospi/tanpi to the CLC library (#133889)
Additionally, these builtins are now vectorized.

This also moves the native_recip and native_divide builtins as they are
used by the tanpi builtin.
2025-04-01 12:03:21 +01:00

115 lines
2.9 KiB
C++

//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#if __CLC_FPSIZE == 32
_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_sinpi(__CLC_GENTYPE x) {
__CLC_INTN ix = __CLC_AS_INTN(x);
__CLC_INTN xsgn = ix & (__CLC_INTN)0x80000000;
ix ^= xsgn;
__CLC_GENTYPE absx = __clc_fabs(x);
__CLC_INTN iax = __CLC_CONVERT_INTN(absx);
__CLC_GENTYPE r = absx - __CLC_CONVERT_GENTYPE(iax);
__CLC_INTN xodd =
xsgn ^ ((iax & 0x1) != 0 ? (__CLC_INTN)0x80000000 : (__CLC_INTN)0);
// Initialize with return for +-Inf and NaN
__CLC_INTN ir = QNANBITPATT_SP32;
// 2^23 <= |x| < Inf, the result is always integer
ir = ix < PINFBITPATT_SP32 ? xsgn : ir;
// 0x1.0p-7 <= |x| < 2^23, result depends on which 0.25 interval
// r < 1.0
__CLC_GENTYPE a = 1.0f - r;
__CLC_INTN e = 0;
// r <= 0.75
__CLC_INTN c = r <= 0.75f;
a = c ? r - 0.5f : a;
e = c ? 1 : e;
// r < 0.5
c = r < 0.5f;
a = c ? 0.5f - r : a;
// 0 < r <= 0.25
c = r <= 0.25f;
a = c ? r : a;
e = c ? 0 : e;
__CLC_GENTYPE sinval, cosval;
__clc_sincos_piby4(a * M_PI_F, &sinval, &cosval);
__CLC_INTN jr = xodd ^ __CLC_AS_INTN(e != 0 ? cosval : sinval);
ir = ix < 0x4b000000 ? jr : ir;
return __CLC_AS_GENTYPE(ir);
}
#elif __CLC_FPSIZE == 64
_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_sinpi(__CLC_GENTYPE x) {
__CLC_LONGN ix = __CLC_AS_LONGN(x);
__CLC_LONGN xsgn = ix & (__CLC_LONGN)0x8000000000000000L;
ix ^= xsgn;
__CLC_GENTYPE absx = __clc_fabs(x);
__CLC_LONGN iax = __CLC_CONVERT_LONGN(absx);
__CLC_GENTYPE r = absx - __CLC_CONVERT_GENTYPE(iax);
__CLC_LONGN xodd =
xsgn ^
((iax & 0x1L) != 0 ? (__CLC_LONGN)0x8000000000000000L : (__CLC_LONGN)0L);
// Initialize with return for +-Inf and NaN
__CLC_LONGN ir = QNANBITPATT_DP64;
// 2^23 <= |x| < Inf, the result is always integer
ir = ix < PINFBITPATT_DP64 ? xsgn : ir;
// 0x1.0p-7 <= |x| < 2^23, result depends on which 0.25 interval
// r < 1.0
__CLC_GENTYPE a = 1.0 - r;
__CLC_LONGN e = 0;
// r <= 0.75
__CLC_LONGN c = r <= 0.75;
__CLC_GENTYPE t = r - 0.5;
a = c ? t : a;
e = c ? 1 : e;
// r < 0.5
c = r < 0.5;
t = 0.5 - r;
a = c ? t : a;
// r <= 0.25
c = r <= 0.25;
a = c ? r : a;
e = c ? 0 : e;
__CLC_GENTYPE api = a * M_PI;
__CLC_GENTYPE sinval, cosval;
__clc_sincos_piby4(api, 0.0, &sinval, &cosval);
__CLC_LONGN jr = xodd ^ __CLC_AS_LONGN(e != 0 ? cosval : sinval);
ir = absx < 0x1.0p+52 ? jr : ir;
return __CLC_AS_GENTYPE(ir);
}
#elif __CLC_FPSIZE == 16
_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_sinpi(__CLC_GENTYPE x) {
return __CLC_CONVERT_GENTYPE(__clc_sinpi(__CLC_CONVERT_FLOATN(x)));
}
#endif