blob: 1c066ad11a58a7c60781a202ab76f34d2c1cd572 [file]
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
_CLC_DEF _CLC_OVERLOAD __CLC_DOUBLEN __clc_get_twobypi_bits(__CLC_DOUBLEN x,
__CLC_INTN index) {
const __CLC_INTN e_clamp = 1077;
__CLC_INTN e = __CLC_CONVERT_INTN(__CLC_AS_ULONGN(x) >> 52);
__CLC_INTN shift = e > e_clamp ? e - e_clamp : 0;
__CLC_INTN scale = e >= 0x7b0 ? 128 : 0;
__CLC_INTN start = shift + index * 53;
__CLC_INTN i = start >> 5;
__CLC_INTN b = start & 0x1f;
__CLC_UINTN w2 = __CLC_USE_TABLE(two_by_pi_bits_tbl, i);
__CLC_UINTN w1 = __CLC_USE_TABLE(two_by_pi_bits_tbl, i + 1);
__CLC_UINTN w0 = __CLC_USE_TABLE(two_by_pi_bits_tbl, i + 2);
__CLC_UINTN t = (w2 << b) | (w1 >> (32 - b));
w2 = b != 0 ? t : w2;
t = (w1 << b) | (w0 >> (32 - b));
w1 = b != 0 ? t : w1;
w1 &= 0xfffff800;
__CLC_INTN z = __CLC_CONVERT_INTN(__clc_clz(w2));
b = 11 - z;
w1 = (w1 >> b) | (w2 << (32 - b));
w2 >>= b;
return __CLC_AS_DOUBLEN(
(__CLC_CONVERT_ULONGN(1022 + scale - start - z) << 52) |
(__CLC_CONVERT_ULONGN(w2 & 0x000fffff) << 32) | __CLC_CONVERT_ULONGN(w1));
}