diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt index a9daa5d9..19f4e654 100644 --- a/libc/CMakeLists.txt +++ b/libc/CMakeLists.txt @@ -25,6 +25,7 @@ set(SOURCES src/termios.cpp src/utime.cpp src/strtod.cpp + src/math.cpp src/sys/stat.cpp src/sys/mman.cpp src/sys/wait.cpp diff --git a/libc/include/math.h b/libc/include/math.h index e69de29b..97682b34 100644 --- a/libc/include/math.h +++ b/libc/include/math.h @@ -0,0 +1,92 @@ +/* math.h: Floating-point arithmetic functions. */ + +#ifndef _MATH_H +#define _MATH_H + +typedef float float_t; +typedef double double_t; + +#define FP_NAN 0 +#define FP_INFINITE 1 +#define FP_ZERO 2 +#define FP_SUBNORMAL 3 +#define FP_NORMAL 4 +#define fpclassify(x) __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_ZERO, FP_SUBNORMAL, FP_ZERO, x) + +#ifdef __cplusplus +extern "C" +{ +#endif + + double cos(double val); + float cosf(float val); + long double cosl(long double val); + double sin(double val); + float sinf(float val); + long double sinl(long double val); + double tan(double val); + float tanf(float val); + long double tanl(long double val); + double acos(double val); + float acosf(float val); + long double acosl(long double val); + double asin(double val); + float asinf(float val); + long double asinl(long double val); + double atan(double val); + float atanf(float val); + long double atanl(long double val); + double cosh(double val); + float coshf(float val); + long double coshl(long double val); + double sinh(double val); + float sinhf(float val); + long double sinhl(long double val); + double tanh(double val); + float tanhf(float val); + long double tanhl(long double val); + double log(double val); + float logf(float val); + long double logl(long double val); + double exp(double val); + float expf(float val); + long double expl(long double val); + double sqrt(double val); + float sqrtf(float val); + long double sqrtl(long double val); + double fabs(double val); + float fabsf(float val); + long double fabsl(long double val); + double floor(double val); + float floorf(float val); + long double floorl(long double val); + double ceil(double val); + float ceilf(float val); + long double ceill(long double val); + double log10(double val); + float log10f(float val); + long double log10l(long double val); + double fmod(double val1, double val2); + float fmodf(float val1, float val2); + long double fmodl(long double val1, long double val2); + double pow(double val1, double val2); + float powf(float val1, float val2); + long double powl(long double val1, long double val2); + double atan2(double val1, double val2); + float atan2f(float val1, float val2); + long double atan2l(long double val1, long double val2); + double frexp(double val1, int* val2); + float frexpf(float val1, int* val2); + long double frexpl(long double val1, int* val2); + double ldexp(double val1, int val2); + float ldexpf(float val1, int val2); + long double ldexpl(long double val1, int val2); + double modf(double val1, double* val2); + float modff(float val1, float* val2); + long double modfl(long double val1, long double* val2); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/src/math.cpp b/libc/src/math.cpp new file mode 100644 index 00000000..52367eb0 --- /dev/null +++ b/libc/src/math.cpp @@ -0,0 +1,106 @@ +#include + +// FIXME: Provide our own definitions instead of relying on the compiler's builtins. + +#define WRAP_AROUND_BUILTIN(name) \ + double name(double val) \ + { \ + return __builtin_##name(val); \ + } \ + float name##f(float val) \ + { \ + return __builtin_##name##f(val); \ + } \ + long double name##l(long double val) \ + { \ + return __builtin_##name##l(val); \ + } + +#define WRAP_AROUND_BUILTIN2(name) \ + double name(double val1, double val2) \ + { \ + return __builtin_##name(val1, val2); \ + } \ + float name##f(float val1, float val2) \ + { \ + return __builtin_##name##f(val1, val2); \ + } \ + long double name##l(long double val1, long double val2) \ + { \ + return __builtin_##name##l(val1, val2); \ + } + +#define WRAP_AROUND_BUILTIN_WITH_PARAMETER_TYPE(name, type) \ + double name(double val1, type val2) \ + { \ + return __builtin_##name(val1, val2); \ + } \ + float name##f(float val1, type val2) \ + { \ + return __builtin_##name##f(val1, val2); \ + } \ + long double name##l(long double val1, type val2) \ + { \ + return __builtin_##name##l(val1, val2); \ + } + +#define WRAP_AROUND_BUILTIN_WITH_POINTER(name) \ + double name(double val1, double* val2) \ + { \ + return __builtin_##name(val1, val2); \ + } \ + float name##f(float val1, float* val2) \ + { \ + return __builtin_##name##f(val1, val2); \ + } \ + long double name##l(long double val1, long double* val2) \ + { \ + return __builtin_##name##l(val1, val2); \ + } + +extern "C" +{ + WRAP_AROUND_BUILTIN(cos); + + WRAP_AROUND_BUILTIN(sin); + + WRAP_AROUND_BUILTIN(tan); + + WRAP_AROUND_BUILTIN(acos); + + WRAP_AROUND_BUILTIN(asin); + + WRAP_AROUND_BUILTIN(atan); + + WRAP_AROUND_BUILTIN(cosh); + + WRAP_AROUND_BUILTIN(sinh); + + WRAP_AROUND_BUILTIN(tanh); + + WRAP_AROUND_BUILTIN(log); + + WRAP_AROUND_BUILTIN(exp); + + WRAP_AROUND_BUILTIN(sqrt); + + WRAP_AROUND_BUILTIN(fabs); + + WRAP_AROUND_BUILTIN(floor); + + WRAP_AROUND_BUILTIN(ceil); + + WRAP_AROUND_BUILTIN(log10); + + WRAP_AROUND_BUILTIN2(fmod); + + WRAP_AROUND_BUILTIN2(pow); + + WRAP_AROUND_BUILTIN2(atan2); + + WRAP_AROUND_BUILTIN_WITH_PARAMETER_TYPE(frexp, int*); + + WRAP_AROUND_BUILTIN_WITH_PARAMETER_TYPE(ldexp, int); + + WRAP_AROUND_BUILTIN_WITH_POINTER(modf); +} \ No newline at end of file