summaryrefslogtreecommitdiff
path: root/libs/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath
blob: fa856b9b80b1b4b76f96edbfec08261781e84c5c (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
#ifndef MSL_CMATH_H_
#define MSL_CMATH_H_

#include <float.h>
#include <arith.h>

#define NAN (*(float*) __float_nan)
#define HUGE_VALF (*(float*) __float_huge)

#if !PLATFORM_GCN
#define HUGE_VAL (*(double*)__double_huge)
#endif

#define M_PI 3.14159265358979323846f
#define M_SQRT3 1.73205f

#define DEG_TO_RAD(degrees) (degrees * (M_PI / 180.0f))
#define RAD_TO_DEG(radians) (radians * (180.0f / M_PI))

#ifdef __cplusplus
extern "C" {
#endif

extern double __frsqrte(double);
extern float __fres(float);
extern double __fabs(double);
extern float __fabsf(float);

int abs(int);
double acos(double);
float acosf(float);
double asin(double);
double atan(double);
double atan2(double, double);
double ceil(double);
double copysign(double, double);
double cos(double);
float cosf(float);
double exp(double);
double floor(double);
double fmod(double, double);
double frexp(double, int*);
double ldexp(double, int);
double modf(double, double*);
double pow(double, double);
float powf(float, float);
double sin(double);
float sinf(float);
double sqrt(double);
double tan(double);
float tanf(float);
double log10(double);

inline double fabs(double f) {
    return __fabs(f);
}

inline long double fabsl(long double x) {
    return fabs((double)x);
}



MSL_INLINE float acosf(float x) {
    return acos(x);
}

MSL_INLINE float atan2f(float y, float x) {
    return (float)atan2(y, x);
}

MSL_INLINE float ceilf(float num) {
    return ceil(num);
}

MSL_INLINE float cosf(float x) {
    return cos(x);
}

MSL_INLINE float expf(float x) {
    return exp(x);
}

MSL_INLINE float floorf(float num) {
    return floor(num);
}

MSL_INLINE float powf(float x, float y) {
    return pow(x, y);
}

MSL_INLINE float sinf(float x) {
    return sin(x);
}

MSL_INLINE float fabsf(float f) {
    return (float)fabs((double)f);
}

MSL_INLINE float fmodf(float f1, float f2) {
    return fmod(f1, f2);
}

MSL_INLINE float log10f(float x) {
    return log10(x);
}

#include "global.h"
#if PLATFORM_WII || PLATFORM_SHIELD
MSL_INLINE float sqrtf(float mag) {
    return sqrt(mag);
}
#else
#ifdef DECOMPCTX
// Hack to mitigate fake mismatches when building from decompctx output
// (which doesn't support precompiled headers).
//
// When built without a PCH, these constants would end up .rodata instead of .data
// which causes a variety of knock-on effects in individual functions' assembly.
//
// Making them into globals is a bit of a hack, but it generally fixes later
// .data and .rodata offsets and allows individual functions to match.
static double _half = 0.5;
static double _three = 3.0;
#endif
MSL_INLINE float sqrtf(float mag) {
#ifndef DECOMPCTX
    // part of the same hack, these are defined outside of the function when using decompctx
    static const double _half = 0.5;
    static const double _three = 3.0;
#endif
    if (mag > 0.0f) {
        double dmag = (double)mag;
        double tmpd = __frsqrte(dmag);
        tmpd = _half * tmpd * (_three - tmpd * tmpd * dmag);
        tmpd = _half * tmpd * (_three - tmpd * tmpd * dmag);
        tmpd = _half * tmpd * (_three - tmpd * tmpd * dmag);
        return (float)(dmag * tmpd);
    } else if (mag < 0.0) {
        return NAN;
    } else if (isnan(mag)) {
        return NAN;
    } else {
        return mag;
    }
}
#endif

MSL_INLINE float tanf(float x) {
    return tan(x);
}

#ifdef __cplusplus
};

namespace std {
template<typename T>
inline double fabs(T x) {
    return ::fabs(x);
}

inline float fabs(float num) {
    return ::fabsf(num);
}

inline float fabsf(float num) {
    return ::fabsf(num);
}

inline float sqrt(float x) {
    return ::sqrtf(x);
}

inline float abs(float x) {
    return ::fabsf(x);
}

inline long abs(long x) {
    return ::labs(x);
}

inline float fmod(float x, float y) {
    return ::fmod(x, y);
}

inline float ceil(float num) {
    return ::ceilf(num);
}

inline float floor(float num) {
    return ::floorf(num);
}

inline float tan(float num) {
    return ::tanf(num);
}

inline float tanf(float num) {
    return ::tanf(num);
}

inline float acos(float num) {
    return ::acosf(num);
}

inline float pow(float x, float y) {
    return ::pow(x, y);
}

inline float pow(float x, int y) {
    // FIXME: Needs to use powf
    return ::pow(x, y);
}
}  // namespace std
#endif

#endif