blob: ce04ce50a6ad5eb6f1dcc4ff3dc34875e539bc7b [file] [log] [blame]
// Some of the Compiler-RT implementations we use want to use functions from
// libm. However, GCC provides builtins for them, so they don't need to show up
// in <math.h> Unfortunately, those GCC builtins seem to (sometimes, at least)
// just emit calls to the functions themselves, so we have our own
// implementations here. They might not be as fast as they could be, but they
// are correct as far as I can tell.
#include <stdint.h>
double fmax(double a, double b) {
if (__builtin_isnan(a)) return b;
if (__builtin_isnan(b)) return a;
if (a > b) return a;
return b;
}
float fmaxf(float a, float b) {
if (__builtin_isnan(a)) return b;
if (__builtin_isnan(b)) return a;
if (a > b) return a;
return b;
}
double scalbn(double x, int exp) {
return x * (2 << exp);
}
float scalbnf(float x, int exp) {
return x * (2 << exp);
}
float logbf(float x) {
union {
float f;
int32_t d;
} converter;
converter.f = x;
int32_t ix = converter.d & 0x7fffffff;
int32_t rix;
if (ix == 0) {
return (float)-1.0 / __builtin_fabsf(x);
} else if (ix >= 0x7f800000) {
return x * x;
} else if (__builtin_expect((rix = ix >> 23) == 0, 0)) {
rix -= __builtin_clz(ix) - 9;
}
return (float)(rix - 127);
}