diff --git a/Cargo.toml b/Cargo.toml index 44fc263..952e39c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,4 +10,5 @@ win32 = [] no_relocs = [] [dependencies] -xgen = { path = "proc_macro"} \ No newline at end of file +xgen = { path = "proc_macro"} +libm = { version = "0.2.8", optional = true } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index c4073f3..41e9c2b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#![no_std] #![feature(decl_macro)] +#![no_std] #![feature(decl_macro,core_intrinsics)] #![allow(unused)] /// Virtual Struct Offset mod vso; @@ -26,6 +26,9 @@ pub use branching::*; mod cffi; pub use cffi::*; +#[cfg(feature = "libm")] mod math; +#[cfg(feature = "libm")] pub use math::*; + /// win32 utilities #[cfg(feature = "win32")] pub mod win32; diff --git a/src/math.rs b/src/math.rs new file mode 100644 index 0000000..6b88d24 --- /dev/null +++ b/src/math.rs @@ -0,0 +1,155 @@ + +//@formatter:off +pub trait Libm: Sized + Copy { + fn acos (self) -> Self; + fn acosh (self) -> Self; + fn asin (self) -> Self; + fn asinh (self) -> Self; + fn atan (self) -> Self; + fn atanh (self) -> Self; + fn cbrt (self) -> Self; + fn ceil (self) -> Self; + fn cos (self) -> Self; + fn cosh (self) -> Self; + fn erfc (self) -> Self; + fn exp (self) -> Self; + fn exp10 (self) -> Self; + fn exp2 (self) -> Self; + fn expm1 (self) -> Self; + fn fabs (self) -> Self; + fn floor (self) -> Self; + fn log (self) -> Self; + fn log10 (self) -> Self; + fn log1p (self) -> Self; + fn log2 (self) -> Self; + fn rint (self) -> Self; + fn round (self) -> Self; + fn sin (self) -> Self; + fn sinh (self) -> Self; + fn sqrt (self) -> Self; + fn tan (self) -> Self; + fn tanh (self) -> Self; + fn tgamma (self) -> Self; + fn trunc (self) -> Self; + fn ilogb (self) -> i32; + fn frexp (self) -> (Self, i32); + fn sincos (self) -> (Self, Self); + fn scalbn (self, i: i32) -> Self; + fn powi (self, i: i32) -> Self; + fn hypot (self, other: Self) -> Self; + fn atan2 (self, other: Self) -> Self; + fn copysign (self, other: Self) -> Self; + fn fdim (self, other: Self) -> Self; + fn fmax (self, other: Self) -> Self; + fn fmin (self, other: Self) -> Self; + fn fmod (self, other: Self) -> Self; + fn nextafter (self, other: Self) -> Self; + fn pow (self, other: Self) -> Self; + fn remainder (self, other: Self) -> Self; + fn remquo (self, other: Self) -> (Self, i32); + fn fma (self, o1: Self, o2: Self) -> Self; +} + +impl Libm for f64 { + fn acos (self) -> Self { libm::acos(self) } + fn acosh (self) -> Self { libm::acosh(self) } + fn asin (self) -> Self { libm::asin(self) } + fn asinh (self) -> Self { libm::asinh(self) } + fn atan (self) -> Self { libm::atan(self) } + fn atanh (self) -> Self { libm::atanh(self) } + fn cbrt (self) -> Self { libm::cbrt(self) } + fn ceil (self) -> Self { libm::ceil(self) } + fn cos (self) -> Self { libm::cos(self) } + fn cosh (self) -> Self { libm::cosh(self) } + fn erfc (self) -> Self { libm::erfc(self) } + fn exp (self) -> Self { libm::exp(self) } + fn exp10 (self) -> Self { libm::exp10(self) } + fn exp2 (self) -> Self { libm::exp2(self) } + fn expm1 (self) -> Self { libm::expm1(self) } + fn fabs (self) -> Self { libm::fabs(self) } + fn floor (self) -> Self { libm::floor(self) } + fn log (self) -> Self { libm::log(self) } + fn log10 (self) -> Self { libm::log10(self) } + fn log1p (self) -> Self { libm::log1p(self) } + fn log2 (self) -> Self { libm::log2(self) } + fn rint (self) -> Self { libm::rint(self) } + fn round (self) -> Self { libm::round(self) } + fn sin (self) -> Self { libm::sin(self) } + fn sinh (self) -> Self { libm::sinh(self) } + fn sqrt (self) -> Self { libm::sqrt(self) } + fn tan (self) -> Self { libm::tan(self) } + fn tanh (self) -> Self { libm::tanh(self) } + fn tgamma (self) -> Self { libm::tgamma(self) } + fn trunc (self) -> Self { libm::trunc(self) } + fn ilogb (self) -> i32 { libm::ilogb(self) } + fn frexp (self) -> (Self, i32) { libm::frexp(self) } + fn sincos (self) -> (Self, Self) { libm::sincos(self) } + fn scalbn (self, i: i32) -> Self { libm::scalbn(self, i) } + fn hypot (self, other: Self) -> Self { libm::hypot(self, other) } + fn atan2 (self, other: Self) -> Self { libm::atan2(self, other) } + fn copysign (self, other: Self) -> Self { libm::copysign(self, other) } + fn fdim (self, other: Self) -> Self { libm::fdim(self, other) } + fn fmax (self, other: Self) -> Self { libm::fmax(self, other) } + fn fmin (self, other: Self) -> Self { libm::fmin(self, other) } + fn fmod (self, other: Self) -> Self { libm::fmod(self, other) } + fn nextafter (self, other: Self) -> Self { libm::nextafter(self, other) } + fn pow (self, other: Self) -> Self { libm::pow(self, other) } + fn remainder (self, other: Self) -> Self { libm::remainder(self, other) } + fn remquo (self, other: Self) -> (Self, i32) { libm::remquo(self, other) } + fn fma (self, o1: Self, o2: Self) -> Self { libm::fma(self, o1, o2) } + + fn powi(self, i: i32) -> Self { unsafe { core::intrinsics::powif64(self, i) } } + +} + +impl Libm for f32 { + fn acos (self) -> Self { libm::acosf(self) } + fn acosh (self) -> Self { libm::acoshf(self) } + fn asin (self) -> Self { libm::asinf(self) } + fn asinh (self) -> Self { libm::asinhf(self) } + fn atan (self) -> Self { libm::atanf(self) } + fn atanh (self) -> Self { libm::atanhf(self) } + fn cbrt (self) -> Self { libm::cbrtf(self) } + fn ceil (self) -> Self { libm::ceilf(self) } + fn cos (self) -> Self { libm::cosf(self) } + fn cosh (self) -> Self { libm::coshf(self) } + fn erfc (self) -> Self { libm::erfcf(self) } + fn exp (self) -> Self { libm::expf(self) } + fn exp10 (self) -> Self { libm::exp10f(self) } + fn exp2 (self) -> Self { libm::exp2f(self) } + fn expm1 (self) -> Self { libm::expm1f(self) } + fn fabs (self) -> Self { libm::fabsf(self) } + fn floor (self) -> Self { libm::floorf(self) } + fn log (self) -> Self { libm::logf(self) } + fn log10 (self) -> Self { libm::log10f(self) } + fn log1p (self) -> Self { libm::log1pf(self) } + fn log2 (self) -> Self { libm::log2f(self) } + fn rint (self) -> Self { libm::rintf(self) } + fn round (self) -> Self { libm::roundf(self) } + fn sin (self) -> Self { libm::sinf(self) } + fn sinh (self) -> Self { libm::sinhf(self) } + fn sqrt (self) -> Self { libm::sqrtf(self) } + fn tan (self) -> Self { libm::tanf(self) } + fn tanh (self) -> Self { libm::tanhf(self) } + fn tgamma (self) -> Self { libm::tgammaf(self) } + fn trunc (self) -> Self { libm::truncf(self) } + fn ilogb (self) -> i32 { libm::ilogbf(self) } + fn frexp (self) -> (Self, i32) { libm::frexpf(self) } + fn sincos (self) -> (Self, Self) { libm::sincosf(self) } + fn scalbn (self, i: i32) -> Self { libm::scalbnf(self, i) } + fn hypot (self, other: Self) -> Self { libm::hypotf(self, other) } + fn atan2 (self, other: Self) -> Self { libm::atan2f(self, other) } + fn copysign (self, other: Self) -> Self { libm::copysignf(self, other) } + fn fdim (self, other: Self) -> Self { libm::fdimf(self, other) } + fn fmax (self, other: Self) -> Self { libm::fmaxf(self, other) } + fn fmin (self, other: Self) -> Self { libm::fminf(self, other) } + fn fmod (self, other: Self) -> Self { libm::fmodf(self, other) } + fn nextafter (self, other: Self) -> Self { libm::nextafterf(self, other) } + fn pow (self, other: Self) -> Self { libm::powf(self, other) } + fn remainder (self, other: Self) -> Self { libm::remainderf(self, other) } + fn remquo (self, other: Self) -> (Self, i32) { libm::remquof(self, other) } + fn fma (self, o1: Self, o2: Self) -> Self { libm::fmaf(self, o1, o2) } + + fn powi(self, i: i32) -> Self { unsafe { core::intrinsics::powif32(self, i) } } + +} \ No newline at end of file diff --git a/tests/test_math.rs b/tests/test_math.rs new file mode 100644 index 0000000..b60418c --- /dev/null +++ b/tests/test_math.rs @@ -0,0 +1,9 @@ + +use x::Libm; + +#[test] +pub fn test_math() { + let a = 2f32.powi(4); + println!("Test: {a}"); + +} \ No newline at end of file