Skip to content

Commit d06e697

Browse files
committed
[libc][math] Refactor exp2 implementation to header-only in src/__support/math folder.
1 parent 074308c commit d06e697

File tree

24 files changed

+620
-576
lines changed

24 files changed

+620
-576
lines changed

libc/shared/math.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "math/exp10f16.h"
4848
#include "math/exp10m1f.h"
4949
#include "math/exp10m1f16.h"
50+
#include "math/exp2.h"
5051
#include "math/expf.h"
5152
#include "math/expf16.h"
5253
#include "math/frexpf.h"

libc/shared/math/exp2.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- Shared exp2 function ------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SHARED_MATH_EXP2_H
10+
#define LLVM_LIBC_SHARED_MATH_EXP2_H
11+
12+
#include "shared/libc_common.h"
13+
#include "src/__support/math/exp2.h"
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
namespace shared {
17+
18+
using math::exp2;
19+
20+
} // namespace shared
21+
} // namespace LIBC_NAMESPACE_DECL
22+
23+
#endif // LLVM_LIBC_SHARED_MATH_EXP2_H

libc/src/__support/math/CMakeLists.txt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,15 @@ add_header_library(
373373
libc.src.__support.macros.optimization
374374
)
375375

376+
add_header_library(
377+
common_constants
378+
HDRS
379+
common_constants.h
380+
DEPENDS
381+
libc.src.__support.macros.config
382+
libc.src.__support.number_pair
383+
)
384+
376385
add_header_library(
377386
cos
378387
HDRS
@@ -704,6 +713,28 @@ add_header_library(
704713
libc.src.__support.macros.optimization
705714
)
706715

716+
add_header_library(
717+
exp2
718+
HDRS
719+
exp2.h
720+
DEPENDS
721+
.common_constants
722+
.exp_utils
723+
libc.src.__support.CPP.bit
724+
libc.src.__support.CPP.optional
725+
libc.src.__support.FPUtil.dyadic_float
726+
libc.src.__support.FPUtil.fenv_impl
727+
libc.src.__support.FPUtil.fp_bits
728+
libc.src.__support.FPUtil.multiply_add
729+
libc.src.__support.FPUtil.nearest_integer
730+
libc.src.__support.FPUtil.polyeval
731+
libc.src.__support.FPUtil.rounding_mode
732+
libc.src.__support.FPUtil.triple_double
733+
libc.src.__support.integer_literals
734+
libc.src.__support.macros.optimization
735+
libc.src.errno.errno
736+
)
737+
707738
add_header_library(
708739
exp10
709740
HDRS

libc/src/math/generic/common_constants.cpp renamed to libc/src/__support/math/common_constants.h

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,37 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "common_constants.h"
9+
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_COMMON_CONSTANTS_H
10+
#define LLVM_LIBC_SRC___SUPPORT_MATH_COMMON_CONSTANTS_H
11+
1012
#include "src/__support/macros/config.h"
1113
#include "src/__support/number_pair.h"
1214

1315
namespace LIBC_NAMESPACE_DECL {
1416

17+
namespace common_constants_internal {
18+
19+
// log(2) generated by Sollya with:
20+
// > a = 2^-43 * nearestint(2^43*log(2));
21+
// LSB = 2^-43 is chosen so that e_x * LOG_2_HI is exact for -1075 < e_x < 1024.
22+
static constexpr double LOG_2_HI = 0x1.62e42fefa38p-1; // LSB = 2^-43
23+
// > b = round(log10(2) - a, D, RN);
24+
static constexpr double LOG_2_LO = 0x1.ef35793c7673p-45; // LSB = 2^-97
25+
26+
// Minimax polynomial for (log(1 + x) - x)/x^2, generated by sollya with:
27+
// > P = fpminimax((log(1 + x) - x)/x^2, 5, [|D...|], [-2^-8, 2^-7]);
28+
constexpr double LOG_COEFFS[6] = {-0x1.fffffffffffffp-2, 0x1.5555555554a9bp-2,
29+
-0x1.0000000094567p-2, 0x1.99999dcc9823cp-3,
30+
-0x1.55550ac2e537ap-3, 0x1.21a02c4e624d7p-3};
31+
1532
// Range reduction constants for logarithms.
1633
// r(0) = 1, r(127) = 0.5
1734
// r(k) = 2^-8 * ceil(2^8 * (1 - 2^-8) / (1 + k*2^-7))
1835
// The constants are chosen so that v = fma(r, m_x, -1) is exact in single
1936
// precision, and -2^-8 <= v < 2^-7.
2037
// TODO(lntue): Add reference to how the constants are derived after the
2138
// resulting paper is ready.
22-
alignas(8) const float R[128] = {
39+
alignas(8) static constexpr float R[128] = {
2340
0x1p0, 0x1.fcp-1, 0x1.f8p-1, 0x1.f4p-1, 0x1.fp-1, 0x1.ecp-1, 0x1.e8p-1,
2441
0x1.e4p-1, 0x1.ep-1, 0x1.dep-1, 0x1.dap-1, 0x1.d6p-1, 0x1.d4p-1, 0x1.dp-1,
2542
0x1.ccp-1, 0x1.cap-1, 0x1.c6p-1, 0x1.c4p-1, 0x1.cp-1, 0x1.bep-1, 0x1.bap-1,
@@ -40,7 +57,7 @@ alignas(8) const float R[128] = {
4057
0x1.0ap-1, 0x1.08p-1, 0x1.08p-1, 0x1.06p-1, 0x1.06p-1, 0x1.04p-1, 0x1.04p-1,
4158
0x1.02p-1, 0x1.0p-1};
4259

43-
const double RD[128] = {
60+
static constexpr double RD[128] = {
4461
0x1p0, 0x1.fcp-1, 0x1.f8p-1, 0x1.f4p-1, 0x1.fp-1, 0x1.ecp-1, 0x1.e8p-1,
4562
0x1.e4p-1, 0x1.ep-1, 0x1.dep-1, 0x1.dap-1, 0x1.d6p-1, 0x1.d4p-1, 0x1.dp-1,
4663
0x1.ccp-1, 0x1.cap-1, 0x1.c6p-1, 0x1.c4p-1, 0x1.cp-1, 0x1.bep-1, 0x1.bap-1,
@@ -65,7 +82,7 @@ const double RD[128] = {
6582
// available.
6683
// Generated by Sollya with the formula: CD[i] = RD[i]*(1 + i*2^-7) - 1
6784
// for RD[i] defined on the table above.
68-
const double CD[128] = {
85+
static constexpr double CD[128] = {
6986
0.0, -0x1p-14, -0x1p-12, -0x1.2p-11, -0x1p-10, -0x1.9p-10,
7087
-0x1.2p-9, -0x1.88p-9, -0x1p-8, -0x1.9p-11, -0x1.fp-10, -0x1.9cp-9,
7188
-0x1p-12, -0x1.cp-10, -0x1.bp-9, -0x1.5p-11, -0x1.4p-9, 0x1p-14,
@@ -90,7 +107,7 @@ const double CD[128] = {
90107
-0x1p-14, -0x1p-8,
91108
};
92109

93-
const double LOG_R[128] = {
110+
static constexpr double LOG_R[128] = {
94111
0x0.0000000000000p0, 0x1.010157588de71p-7, 0x1.0205658935847p-6,
95112
0x1.8492528c8cabfp-6, 0x1.0415d89e74444p-5, 0x1.466aed42de3eap-5,
96113
0x1.894aa149fb343p-5, 0x1.ccb73cdddb2ccp-5, 0x1.08598b59e3a07p-4,
@@ -135,7 +152,7 @@ const double LOG_R[128] = {
135152
0x1.5707a26bb8c66p-1, 0x1.5af405c3649ep-1, 0x1.5af405c3649ep-1,
136153
0x1.5ee82aa24192p-1, 0x0.000000000000p0};
137154

138-
const double LOG2_R[128] = {
155+
static constexpr double LOG2_R[128] = {
139156
0x0.0000000000000p+0, 0x1.72c7ba20f7327p-7, 0x1.743ee861f3556p-6,
140157
0x1.184b8e4c56af8p-5, 0x1.77394c9d958d5p-5, 0x1.d6ebd1f1febfep-5,
141158
0x1.1bb32a600549dp-4, 0x1.4c560fe68af88p-4, 0x1.7d60496cfbb4cp-4,
@@ -188,7 +205,7 @@ const double LOG2_R[128] = {
188205
// print("{", -c, ",", -b, "},");
189206
// };
190207
// We replace LOG_R[0] with log10(1.0) == 0.0
191-
alignas(16) const NumberPair<double> LOG_R_DD[128] = {
208+
alignas(16) static constexpr NumberPair<double> LOG_R_DD[128] = {
192209
{0.0, 0.0},
193210
{-0x1.0c76b999d2be8p-46, 0x1.010157589p-7},
194211
{-0x1.3dc5b06e2f7d2p-45, 0x1.0205658938p-6},
@@ -324,7 +341,7 @@ alignas(16) const NumberPair<double> LOG_R_DD[128] = {
324341
// Output range:
325342
// [-0x1.3ffcp-15, 0x1.3e3dp-15]
326343
// We store S2[i] = 2^16 (r(i - 2^6) - 1).
327-
alignas(8) const int S2[193] = {
344+
alignas(8) static constexpr int S2[193] = {
328345
0x101, 0xfd, 0xf9, 0xf5, 0xf1, 0xed, 0xe9, 0xe5, 0xe1,
329346
0xdd, 0xd9, 0xd5, 0xd1, 0xcd, 0xc9, 0xc5, 0xc1, 0xbd,
330347
0xb9, 0xb4, 0xb0, 0xac, 0xa8, 0xa4, 0xa0, 0x9c, 0x98,
@@ -348,7 +365,7 @@ alignas(8) const int S2[193] = {
348365
-0x1cd, -0x1d1, -0x1d5, -0x1d9, -0x1dd, -0x1e0, -0x1e4, -0x1e8, -0x1ec,
349366
-0x1f0, -0x1f4, -0x1f8, -0x1fc};
350367

351-
const double R2[193] = {
368+
static constexpr double R2[193] = {
352369
0x1.0101p0, 0x1.00fdp0, 0x1.00f9p0, 0x1.00f5p0, 0x1.00f1p0,
353370
0x1.00edp0, 0x1.00e9p0, 0x1.00e5p0, 0x1.00e1p0, 0x1.00ddp0,
354371
0x1.00d9p0, 0x1.00d5p0, 0x1.00d1p0, 0x1.00cdp0, 0x1.00c9p0,
@@ -395,7 +412,7 @@ const double R2[193] = {
395412
// Output range:
396413
// [-0x1.01928p-22 , 0x1p-22]
397414
// We store S[i] = 2^21 (r(i - 80) - 1).
398-
alignas(8) const int S3[161] = {
415+
alignas(8) static constexpr int S3[161] = {
399416
0x50, 0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, 0x47, 0x46,
400417
0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b,
401418
0x3a, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30,
@@ -418,7 +435,7 @@ alignas(8) const int S3[161] = {
418435
// Output range:
419436
// [-0x1.0002143p-29 , 0x1p-29]
420437
// We store S[i] = 2^28 (r(i - 65) - 1).
421-
alignas(8) const int S4[130] = {
438+
alignas(8) static constexpr int S4[130] = {
422439
0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37,
423440
0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c,
424441
0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21,
@@ -439,7 +456,7 @@ alignas(8) const int S4[130] = {
439456
// Table is generated with Sollya as follow:
440457
// > display = hexadecimal;
441458
// > for i from -104 to 89 do { D(exp(i)); };
442-
const double EXP_M1[195] = {
459+
static constexpr double EXP_M1[195] = {
443460
0x1.f1e6b68529e33p-151, 0x1.525be4e4e601dp-149, 0x1.cbe0a45f75eb1p-148,
444461
0x1.3884e838aea68p-146, 0x1.a8c1f14e2af5dp-145, 0x1.20a717e64a9bdp-143,
445462
0x1.8851d84118908p-142, 0x1.0a9bdfb02d240p-140, 0x1.6a5bea046b42ep-139,
@@ -511,7 +528,7 @@ const double EXP_M1[195] = {
511528
// Table is generated with Sollya as follow:
512529
// > display = hexadecimal;
513530
// > for i from 0 to 127 do { D(exp(i / 128)); };
514-
const double EXP_M2[128] = {
531+
static constexpr double EXP_M2[128] = {
515532
0x1.0000000000000p0, 0x1.0202015600446p0, 0x1.04080ab55de39p0,
516533
0x1.06122436410ddp0, 0x1.08205601127edp0, 0x1.0a32a84e9c1f6p0,
517534
0x1.0c49236829e8cp0, 0x1.0e63cfa7ab09dp0, 0x1.1082b577d34edp0,
@@ -557,4 +574,8 @@ const double EXP_M2[128] = {
557574
0x1.568bb722dd593p1, 0x1.593b7d72305bbp1,
558575
};
559576

577+
} // namespace common_constants_internal
578+
560579
} // namespace LIBC_NAMESPACE_DECL
580+
581+
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COMMON_CONSTANTS_H

0 commit comments

Comments
 (0)