//===-- 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