-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into greg/sqlite
- Loading branch information
Showing
69 changed files
with
8,558 additions
and
469 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#include "libm.h" | ||
|
||
double __kadena_math_divzero(uint32_t sign) | ||
{ | ||
return fp_barrier(sign ? -1.0 : 1.0) / 0.0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#include "libm.h" | ||
|
||
double __kadena_math_invalid(double x) | ||
{ | ||
return (x - x) / (x - x); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#include "libm.h" | ||
|
||
double __kadena_math_oflow(uint32_t sign) | ||
{ | ||
return __kadena_math_xflow(sign, 0x1p769); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#include "libm.h" | ||
|
||
double __kadena_math_uflow(uint32_t sign) | ||
{ | ||
return __kadena_math_xflow(sign, 0x1p-767); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#include "libm.h" | ||
|
||
double __kadena_math_xflow(uint32_t sign, double y) | ||
{ | ||
return eval_as_double(fp_barrier(sign ? -y : y) * y); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#ifndef _ENDIAN_H | ||
#define _ENDIAN_H | ||
|
||
/*#include <features.h>*/ | ||
|
||
#define __NEED_uint16_t | ||
#define __NEED_uint32_t | ||
#define __NEED_uint64_t | ||
|
||
/*#include <bits/alltypes.h>*/ | ||
|
||
#define __PDP_ENDIAN 3412 | ||
|
||
#define BIG_ENDIAN __BIG_ENDIAN | ||
#define LITTLE_ENDIAN __LITTLE_ENDIAN | ||
#define PDP_ENDIAN __PDP_ENDIAN | ||
#define BYTE_ORDER __BYTE_ORDER | ||
|
||
static __inline uint16_t __bswap16(uint16_t __x) | ||
{ | ||
return __x<<8 | __x>>8; | ||
} | ||
|
||
static __inline uint32_t __bswap32(uint32_t __x) | ||
{ | ||
return __x>>24 | __x>>8&0xff00 | __x<<8&0xff0000 | __x<<24; | ||
} | ||
|
||
static __inline uint64_t __bswap64(uint64_t __x) | ||
{ | ||
return __bswap32(__x)+0ULL<<32 | __bswap32(__x>>32); | ||
} | ||
|
||
#if __BYTE_ORDER == __LITTLE_ENDIAN | ||
#define htobe16(x) __bswap16(x) | ||
#define be16toh(x) __bswap16(x) | ||
#define htobe32(x) __bswap32(x) | ||
#define be32toh(x) __bswap32(x) | ||
#define htobe64(x) __bswap64(x) | ||
#define be64toh(x) __bswap64(x) | ||
#define htole16(x) (uint16_t)(x) | ||
#define le16toh(x) (uint16_t)(x) | ||
#define htole32(x) (uint32_t)(x) | ||
#define le32toh(x) (uint32_t)(x) | ||
#define htole64(x) (uint64_t)(x) | ||
#define le64toh(x) (uint64_t)(x) | ||
#else | ||
#define htobe16(x) (uint16_t)(x) | ||
#define be16toh(x) (uint16_t)(x) | ||
#define htobe32(x) (uint32_t)(x) | ||
#define be32toh(x) (uint32_t)(x) | ||
#define htobe64(x) (uint64_t)(x) | ||
#define be64toh(x) (uint64_t)(x) | ||
#define htole16(x) __bswap16(x) | ||
#define le16toh(x) __bswap16(x) | ||
#define htole32(x) __bswap32(x) | ||
#define le32toh(x) __bswap32(x) | ||
#define htole64(x) __bswap64(x) | ||
#define le64toh(x) __bswap64(x) | ||
#endif | ||
|
||
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) | ||
#if __BYTE_ORDER == __LITTLE_ENDIAN | ||
#define betoh16(x) __bswap16(x) | ||
#define betoh32(x) __bswap32(x) | ||
#define betoh64(x) __bswap64(x) | ||
#define letoh16(x) (uint16_t)(x) | ||
#define letoh32(x) (uint32_t)(x) | ||
#define letoh64(x) (uint64_t)(x) | ||
#else | ||
#define betoh16(x) (uint16_t)(x) | ||
#define betoh32(x) (uint32_t)(x) | ||
#define betoh64(x) (uint64_t)(x) | ||
#define letoh16(x) __bswap16(x) | ||
#define letoh32(x) __bswap32(x) | ||
#define letoh64(x) __bswap64(x) | ||
#endif | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
/* | ||
* Double-precision e^x function. | ||
* | ||
* Copyright (c) 2018, Arm Limited. | ||
* SPDX-License-Identifier: MIT | ||
*/ | ||
|
||
#include <math.h> | ||
#include <stdint.h> | ||
#include "libm.h" | ||
#include "exp_data.h" | ||
|
||
#define N (1 << EXP_TABLE_BITS) | ||
#define InvLn2N __kadena_exp_data.invln2N | ||
#define NegLn2hiN __kadena_exp_data.negln2hiN | ||
#define NegLn2loN __kadena_exp_data.negln2loN | ||
#define Shift __kadena_exp_data.shift | ||
#define T __kadena_exp_data.tab | ||
#define C2 __kadena_exp_data.poly[5 - EXP_POLY_ORDER] | ||
#define C3 __kadena_exp_data.poly[6 - EXP_POLY_ORDER] | ||
#define C4 __kadena_exp_data.poly[7 - EXP_POLY_ORDER] | ||
#define C5 __kadena_exp_data.poly[8 - EXP_POLY_ORDER] | ||
|
||
/* Handle cases that may overflow or underflow when computing the result that | ||
is scale*(1+TMP) without intermediate rounding. The bit representation of | ||
scale is in SBITS, however it has a computed exponent that may have | ||
overflown into the sign bit so that needs to be adjusted before using it as | ||
a double. (int32_t)KI is the k used in the argument reduction and exponent | ||
adjustment of scale, positive k here means the result may overflow and | ||
negative k means the result may underflow. */ | ||
static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki) | ||
{ | ||
double_t scale, y; | ||
|
||
if ((ki & 0x80000000) == 0) { | ||
/* k > 0, the exponent of scale might have overflowed by <= 460. */ | ||
sbits -= 1009ull << 52; | ||
scale = asdouble(sbits); | ||
y = 0x1p1009 * (scale + scale * tmp); | ||
return eval_as_double(y); | ||
} | ||
/* k < 0, need special care in the subnormal range. */ | ||
sbits += 1022ull << 52; | ||
scale = asdouble(sbits); | ||
y = scale + scale * tmp; | ||
if (y < 1.0) { | ||
/* Round y to the right precision before scaling it into the subnormal | ||
range to avoid double rounding that can cause 0.5+E/2 ulp error where | ||
E is the worst-case ulp error outside the subnormal range. So this | ||
is only useful if the goal is better than 1 ulp worst-case error. */ | ||
double_t hi, lo; | ||
lo = scale - y + scale * tmp; | ||
hi = 1.0 + y; | ||
lo = 1.0 - hi + y + lo; | ||
y = eval_as_double(hi + lo) - 1.0; | ||
/* Avoid -0.0 with downward rounding. */ | ||
if (WANT_ROUNDING && y == 0.0) | ||
y = 0.0; | ||
/* The underflow exception needs to be signaled explicitly. */ | ||
fp_force_eval(fp_barrier(0x1p-1022) * 0x1p-1022); | ||
} | ||
y = 0x1p-1022 * y; | ||
return eval_as_double(y); | ||
} | ||
|
||
/* Top 12 bits of a double (sign and exponent bits). */ | ||
static inline uint32_t top12(double x) | ||
{ | ||
return asuint64(x) >> 52; | ||
} | ||
|
||
double musl_exp(double x) | ||
{ | ||
uint32_t abstop; | ||
uint64_t ki, idx, top, sbits; | ||
double_t kd, z, r, r2, scale, tail, tmp; | ||
|
||
abstop = top12(x) & 0x7ff; | ||
if (predict_false(abstop - top12(0x1p-54) >= top12(512.0) - top12(0x1p-54))) { | ||
if (abstop - top12(0x1p-54) >= 0x80000000) | ||
/* Avoid spurious underflow for tiny x. */ | ||
/* Note: 0 is common input. */ | ||
return WANT_ROUNDING ? 1.0 + x : 1.0; | ||
if (abstop >= top12(1024.0)) { | ||
if (asuint64(x) == asuint64(-INFINITY)) | ||
return 0.0; | ||
if (abstop >= top12(INFINITY)) | ||
return 1.0 + x; | ||
if (asuint64(x) >> 63) | ||
return __kadena_math_uflow(0); | ||
else | ||
return __kadena_math_oflow(0); | ||
} | ||
/* Large x is special cased below. */ | ||
abstop = 0; | ||
} | ||
|
||
/* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]. */ | ||
/* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]. */ | ||
z = InvLn2N * x; | ||
#if TOINT_INTRINSICS | ||
kd = roundtoint(z); | ||
ki = converttoint(z); | ||
#elif EXP_USE_TOINT_NARROW | ||
/* z - kd is in [-0.5-2^-16, 0.5] in all rounding modes. */ | ||
kd = eval_as_double(z + Shift); | ||
ki = asuint64(kd) >> 16; | ||
kd = (double_t)(int32_t)ki; | ||
#else | ||
/* z - kd is in [-1, 1] in non-nearest rounding modes. */ | ||
kd = eval_as_double(z + Shift); | ||
ki = asuint64(kd); | ||
kd -= Shift; | ||
#endif | ||
r = x + kd * NegLn2hiN + kd * NegLn2loN; | ||
/* 2^(k/N) ~= scale * (1 + tail). */ | ||
idx = 2 * (ki % N); | ||
top = ki << (52 - EXP_TABLE_BITS); | ||
tail = asdouble(T[idx]); | ||
/* This is only a valid scale when -1023*N < k < 1024*N. */ | ||
sbits = T[idx + 1] + top; | ||
/* exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1). */ | ||
/* Evaluation is optimized assuming superscalar pipelined execution. */ | ||
r2 = r * r; | ||
/* Without fma the worst case error is 0.25/N ulp larger. */ | ||
/* Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp. */ | ||
tmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5); | ||
if (predict_false(abstop == 0)) | ||
return specialcase(tmp, sbits, ki); | ||
scale = asdouble(sbits); | ||
/* Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there | ||
is no spurious underflow here even without fma. */ | ||
return eval_as_double(scale + scale * tmp); | ||
} |
Oops, something went wrong.