llvm/libc/src/math/generic/common_constants.cpp

//===-- Common constants for math functions ---------------------*- 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
//
//===----------------------------------------------------------------------===//

#include "common_constants.h"
#include "src/__support/FPUtil/triple_double.h"
#include "src/__support/macros/config.h"
#include "src/__support/number_pair.h"

namespace LIBC_NAMESPACE_DECL {

// Lookup table for (1/f) where f = 1 + n*2^(-7), n = 0..127.
const double ONE_OVER_F[128] =;

// Lookup table for log(f) = log(1 + n*2^(-7)) where n = 0..127.
const double LOG_F[128] =;

// Range reduction constants for logarithms.
// r(0) = 1, r(127) = 0.5
// r(k) = 2^-8 * ceil(2^8 * (1 - 2^-8) / (1 + k*2^-7))
// The constants are chosen so that v = fma(r, m_x, -1) is exact in single
// precision, and -2^-8 <= v < 2^-7.
// TODO(lntue): Add reference to how the constants are derived after the
// resulting paper is ready.
alignas(32) const float R[128] =;

alignas(64) const double RD[128] =;

// Compensated constants for exact logarithm range reduction when FMA is not
// available.
// Generated by Sollya with the formula: CD[i] = RD[i]*(1 + i*2^-7) - 1
// for RD[i] defined on the table above.
alignas(64) const double CD[128] =;

alignas(64) const double LOG_R[128] =;

alignas(64) const double LOG2_R[128] =;

// Generated by Sollya with:
// for i from 0 to 127 do {
//     r = 2^-8 * ceil( 2^8 * (1 - 2^(-8)) / (1 + i*2^-7) );
//     b = nearestint(log(r)*2^43) * 2^-43;
//     c = round(log(r) - b, D, RN);
//     print("{", -c, ",", -b, "},");
//   };
// We replace LOG_R[0] with log10(1.0) == 0.0
alignas(64) const NumberPair<double> LOG_R_DD[128] =;

// Logarithm range reduction - Step 2:
//   r(k) = 2^-16 round(2^16 / (1 + k*2^-14)) for k = -2^6 .. 2^7.
// Output range:
//   [-0x1.3ffcp-15, 0x1.3e3dp-15]
// We store S2[i] = 2^16 (r(i - 2^6) - 1).
alignas(64) const int S2[193] =;

alignas(64) const double R2[193] =;

// Logarithm range reduction - Step 3:
//   r(k) = 2^-21 round(2^21 / (1 + k*2^-21)) for k = -80 .. 80.
// Output range:
//   [-0x1.01928p-22 , 0x1p-22]
// We store S[i] = 2^21 (r(i - 80) - 1).
alignas(64) const int S3[161] =;

// Logarithm range reduction - Step 4
//   r(k) = 2^-28 round(2^28 / (1 + k*2^-28)) for k = -65 .. 64.
// Output range:
//   [-0x1.0002143p-29 , 0x1p-29]
// We store S[i] = 2^28 (r(i - 65) - 1).
alignas(64) const int S4[130] =;

// Lookup table for exp(m) with m = -104, ..., 89.
//   -104 = floor(log(single precision's min denormal))
//     89 = ceil(log(single precision's max normal))
// Table is generated with Sollya as follow:
// > display = hexadecimal;
// > for i from -104 to 89 do { D(exp(i)); };
const double EXP_M1[195] =;

// Lookup table for exp(m * 2^(-7)) with m = 0, ..., 127.
// Table is generated with Sollya as follow:
// > display = hexadecimal;
// > for i from 0 to 127 do { D(exp(i / 128)); };
const double EXP_M2[128] =;

// Lookup table for 2^(k * 2^-6) with k = 0..63.
// Generated by Sollya with:
// > display=hexadecimal;
// > prec = 500;
// > for i from 0 to 63 do {
//     a = 2^(i * 2^-6);
//     b = round(a, D, RN);
//     c = round(a - b, D, RN);
//     d = round(a - b - c, D, RN);
//     print("{", d, ",", c, ",", b, "},");
//   };
const fputil::TripleDouble EXP2_MID1[64] =;

// Lookup table for 2^(k * 2^-12) with k = 0..63.
// Generated by Sollya with:
// > display=hexadecimal;
// > prec = 500;
// > for i from 0 to 63 do {
//     a = 2^(i * 2^-12);
//     b = round(a, D, RN);
//     c = round(a - b, D, RN);
//     d = round(a - b - c, D, RN);
//     print("{", d, ",", c, ",", b, "},");
//   };
const fputil::TripleDouble EXP2_MID2[64] =;

} // namespace LIBC_NAMESPACE_DECL