blob: ce04ce50a6ad5eb6f1dcc4ff3dc34875e539bc7b [file] [log] [blame]
Brian Silverman5da98032013-04-28 18:08:57 -07001// Some of the Compiler-RT implementations we use want to use functions from
2// libm. However, GCC provides builtins for them, so they don't need to show up
3// in <math.h> Unfortunately, those GCC builtins seem to (sometimes, at least)
4// just emit calls to the functions themselves, so we have our own
5// implementations here. They might not be as fast as they could be, but they
6// are correct as far as I can tell.
7
8#include <stdint.h>
9
10double fmax(double a, double b) {
11 if (__builtin_isnan(a)) return b;
12 if (__builtin_isnan(b)) return a;
13 if (a > b) return a;
14 return b;
15}
16float fmaxf(float a, float b) {
17 if (__builtin_isnan(a)) return b;
18 if (__builtin_isnan(b)) return a;
19 if (a > b) return a;
20 return b;
21}
22
23double scalbn(double x, int exp) {
24 return x * (2 << exp);
25}
26float scalbnf(float x, int exp) {
27 return x * (2 << exp);
28}
29
30float logbf(float x) {
31 union {
32 float f;
33 int32_t d;
34 } converter;
35 converter.f = x;
36 int32_t ix = converter.d & 0x7fffffff;
37 int32_t rix;
38
39 if (ix == 0) {
40 return (float)-1.0 / __builtin_fabsf(x);
41 } else if (ix >= 0x7f800000) {
42 return x * x;
43 } else if (__builtin_expect((rix = ix >> 23) == 0, 0)) {
44 rix -= __builtin_clz(ix) - 9;
45 }
46 return (float)(rix - 127);
47}