namespace rgpot::simd::detail¶
Overview¶
namespace detail {
// global variables
double kFmaSplit = 134217729.0;
double kExpInvLn2 = 0x1.71547652b82fep0;
double kExpLn2Hi = 0x1.62e42feep-1;
double kExpLn2Lo = 0x1.a39ef35793c76p-33;
double kExpShift = 0x1.8p52;
double kExpMax = 710.0;
double kExpMin = -746.0;
double kExpC2 = 0x1.000000000000ap-1;
double kExpC3 = 0x1.55555555554fep-3;
double kExpC4 = 0x1.55555555506bcp-5;
double kExpC5 = 0x1.1111111126b36p-7;
double kExpC6 = 0x1.6c16c18477083p-10;
double kExpC7 = 0x1.a01a012fee99cp-13;
double kExpC8 = 0x1.a019995efb00fp-16;
double kExpC9 = 0x1.71df18ef76144p-19;
double kExpC10 = 0x1.28adfccb26cd8p-22;
double kExpC11 = 0x1.ad92e899366cbp-26;
// global functions
void two_sum(double a, double b, double& s, double& e);
void two_prod(double a, double b, double& p, double& e);
bool fma_hw_active();
std::uint64_t bits_of(double x);
double from_bits(std::uint64_t u);
bool exp_in_band(std::uint64_t u, unsigned lo, unsigned hi);
bool fma_ro_domain(double a, double b, double c);
double fma_ro(double a, double b, double c, bool& exact_ok);
std::uint64_t exp_bits(double x);
double exp_from_bits(std::uint64_t u);
double exp_pow2(double m);
double exp_fixed_lane(double x);
} // namespace detail
Detailed Documentation¶
Global Functions¶
bool fma_hw_active()
True when the hardware fused multiply-add may run: the CPU has FMA3 and the OS saves its registers (CPUID), glibc 2.33 or newer does not mask it, and RGPOT_FMA is not software. Read once per process. The hardware instruction and the software path return the same bits, so this decides speed only.
double exp_pow2(double m)
2^m for an integer-valued m in [-1022, 1023], built in the exponent field. m + 1023 lands in the low bits of the shifted sum.
double exp_fixed_lane(double x)
The body every exp in rgpot runs, scalar or as a vector lane. Branch free: GCC and clang vectorise a loop over it. NaN propagates, +inf gives +inf and -inf gives +0.