summaryrefslogtreecommitdiffstats
path: root/floattypes.h
blob: fa4cc4499455d16d737dac60f92836a1b6ea23da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
// -*-C++-*-

#ifndef FLOATTYPES_H
#define FLOATTYPES_H

#include <cassert>
#include <cstdlib>

#if !(defined __clang__ || defined __gcc__)
#define __builtin_unreachable() (assert(0))
#define __builtin_expect(expr, val) (expr)
#endif

// We expect either 199711L or 201103L
#if __cplusplus >= 201103L
// C++11 is supported, use it

#include <cmath>
#include <cstdint>

namespace vml_std {
using namespace std;
}

#else
// C++11 is not supported, work around the missing pieces

// <cmath> does not work with all compilers; e.g. IBM's xlC on a Blue
// Gene/Q then does not provide macros for isnan, but provides
// functions instead.
#include <math.h>
#include <stdint.h>

#ifndef static_assert
#define VML_CONCAT2(x, y) x##y
#define VML_CONCAT(x, y) VML_CONCAT2(x, y)
#define static_assert(cond, msg)                                               \
  typedef int VML_CONCAT(vml_static_assert_, __LINE__)[(cond) ? 1 : -1]        \
      __attribute__((__unused__))
#endif

// Capture libc macros, then undefine them
#ifndef isfinite
#error "isfinite is not a macro"
#endif
#ifndef isinf
#error "isinf is not a macro"
#endif
#ifndef isnan
#error "isnan is not a macro"
#endif
#ifndef isnormal
#error "isnormal is not a macro"
#endif
#ifndef signbit
#error "signbit is not a macro"
#endif

namespace {
template <typename T> inline int libc_isfinite(T x) { return isfinite(x); }
template <typename T> inline int libc_isinf(T x) { return isinf(x); }
template <typename T> inline int libc_isnan(T x) { return isnan(x); }
template <typename T> inline int libc_isnormal(T x) { return isnormal(x); }
template <typename T> inline int libc_signbit(T x) { return signbit(x); }
}

// Include this before undefining the macros below
#include <cmath>

#undef isfinite
#undef isinf
#undef isnon
#undef isnormal
#undef signbit

namespace vml_std {

// Make some type definitions from stdint.h available in std
typedef ::uint8_t uint8_t;
typedef ::int8_t int8_t;
typedef ::uint16_t uint16_t;
typedef ::int16_t int16_t;
typedef ::uint32_t uint32_t;
typedef ::int32_t int32_t;
#if __SIZEOF_LONG__ == 8
// Even if both "long" and "long long" have the same size, they are
// still different types. In many cases, it is then preferable to
// use "long" instead of "long long".
typedef unsigned long uint64_t;
typedef long int64_t;
#else
typedef ::uint64_t uint64_t;
typedef ::int64_t int64_t;
#endif

// Make math functions from math.h available in vml_std
// (We could instead take some of them -- but not all -- from std.)

inline float acos(float x) { return ::acosf(x); }
inline float acosh(float x) { return ::acoshf(x); }
inline float asin(float x) { return ::asinf(x); }
inline float asinh(float x) { return ::asinhf(x); }
inline float atan(float x) { return ::atanf(x); }
inline float atan2(float x, float y) { return ::atan2f(x, y); }
inline float atanh(float x) { return ::atanhf(x); }
inline float cbrt(float x) { return ::cbrtf(x); }
inline float ceil(float x) { return ::ceilf(x); }
inline float cos(float x) { return ::cosf(x); }
inline float cosh(float x) { return ::coshf(x); }
inline float copysign(float x, float y) { return ::copysignf(x, y); }
inline float exp(float x) { return ::expf(x); }
inline float exp2(float x) { return ::exp2f(x); }
inline float expm1(float x) { return ::expm1f(x); }
inline float fabs(float x) { return ::fabsf(x); }
inline float fdim(float x, float y) { return ::fdimf(x, y); }
inline float floor(float x) { return ::floorf(x); }
inline float fma(float x, float y, float z) { return ::fmaf(x, y, z); }
inline float fmax(float x, float y) { return ::fmaxf(x, y); }
inline float fmin(float x, float y) { return ::fminf(x, y); }
inline float fmod(float x, float y) { return ::fmodf(x, y); }
inline float frexp(float x, int *r) { return ::frexpf(x, r); }
inline float hypot(float x, float y) { return ::hypotf(x, y); }
inline int ilogb(float x) { return ::ilogbf(x); }
inline bool isfinite(float x) { return libc_isfinite(x); }
inline bool isinf(float x) { return libc_isinf(x); }
inline bool isnan(float x) { return libc_isnan(x); }
inline bool isnormal(float x) { return libc_isnormal(x); }
inline float ldexp(float x, int n) { return ::ldexpf(x, n); }
inline long long llrint(float x) { return ::llrintf(x); }
inline float log(float x) { return ::logf(x); }
inline float log10(float x) { return ::log10f(x); }
inline float log1p(float x) { return ::log1pf(x); }
inline float log2(float x) { return ::log2f(x); }
inline long lrint(float x) { return ::lrintf(x); }
inline float nextafter(float x, float y) { return ::nextafterf(x, y); }
inline float pow(float x, float y) { return ::powf(x, y); }
inline float remainder(float x, float y) { return ::remainderf(x, y); }
inline float rint(float x) { return ::rintf(x); }
inline float round(float x) { return ::roundf(x); }
inline bool signbit(float x) { return libc_signbit(x); }
inline float sin(float x) { return ::sinf(x); }
inline float sinh(float x) { return ::sinhf(x); }
inline float sqrt(float x) { return ::sqrtf(x); }
inline float tan(float x) { return ::tanf(x); }
inline float tanh(float x) { return ::tanhf(x); }
inline float trunc(float x) { return ::truncf(x); }

inline double acos(double x) { return ::acos(x); }
inline double acosh(double x) { return ::acosh(x); }
inline double asin(double x) { return ::asin(x); }
inline double asinh(double x) { return ::asinh(x); }
inline double atan(double x) { return ::atan(x); }
inline double atan2(double x, double y) { return ::atan2(x, y); }
inline double atanh(double x) { return ::atanh(x); }
inline double cbrt(double x) { return ::cbrt(x); }
inline double ceil(double x) { return ::ceil(x); }
inline double cos(double x) { return ::cos(x); }
inline double cosh(double x) { return ::cosh(x); }
inline double copysign(double x, double y) { return ::copysign(x, y); }
inline double exp(double x) { return ::exp(x); }
inline double exp2(double x) { return ::exp2(x); }
inline double expm1(double x) { return ::expm1(x); }
inline double fabs(double x) { return ::fabs(x); }
inline double fdim(double x, double y) { return ::fdim(x, y); }
inline double floor(double x) { return ::floor(x); }
inline double fma(double x, double y, double z) { return ::fma(x, y, z); }
inline double fmax(double x, double y) { return ::fmax(x, y); }
inline double fmin(double x, double y) { return ::fmin(x, y); }
inline double fmod(double x, double y) { return ::fmod(x, y); }
inline double frexp(double x, int *r) { return ::frexp(x, r); }
inline double hypot(double x, double y) { return ::hypot(x, y); }
inline int ilogb(double x) { return ::ilogb(x); }
inline bool isfinite(double x) { return libc_isfinite(x); }
inline bool isinf(double x) { return libc_isinf(x); }
inline bool isnan(double x) { return libc_isnan(x); }
inline bool isnormal(double x) { return libc_isnormal(x); }
inline double ldexp(double x, int n) { return ::ldexp(x, n); }
inline long long llrint(double x) { return ::llrint(x); }
inline double log(double x) { return ::log(x); }
inline double log10(double x) { return ::log10(x); }
inline double log1p(double x) { return ::log1p(x); }
inline double log2(double x) { return ::log2(x); }
inline long lrint(double x) { return ::lrint(x); }
inline double nextafter(double x, double y) { return ::nextafter(x, y); }
inline double pow(double x, double y) { return ::pow(x, y); }
inline double remainder(double x, double y) { return ::remainder(x, y); }
inline double rint(double x) { return ::rint(x); }
inline double round(double x) { return ::round(x); }
inline bool signbit(double x) { return libc_signbit(x); }
inline double sin(double x) { return ::sin(x); }
inline double sinh(double x) { return ::sinh(x); }
inline double sqrt(double x) { return ::sqrt(x); }
inline double tan(double x) { return ::tan(x); }
inline double tanh(double x) { return ::tanh(x); }
inline double trunc(double x) { return ::trunc(x); }
}

#endif

namespace vecmathlib {

struct fp8 {
  // 1 bit sign, 4 bits exponent, 3 bits mantissa, exponent offset 7 (?)
  vml_std::uint8_t val;
  fp8() {}
  fp8(double x) { __builtin_unreachable(); }
};

struct fp16 {
  // 1 bit sign, 5 bits exponent, 10 bits mantissa, exponent offset 15 (?)
  vml_std::uint16_t val;
  fp16() {}
  fp16(double x) { __builtin_unreachable(); }
};

} // namespace vecmathlib

#endif // #ifndef FLOATTYPES_H
OpenPOWER on IntegriCloud