From d6c6477977dff6fef8521b3fc3f6bf0bf02a4246 Mon Sep 17 00:00:00 2001 From: Renar Narubin Date: Tue, 30 Nov 2021 22:35:16 -0800 Subject: [PATCH] Neg in C --- src/lib.rs | 28 +--------------------------- src/math/math.c | 7 +++++++ src/math/mod.rs | 22 +++++++++++++++++++++- 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 145728a..17b5381 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,7 @@ use core::{ cmp, fmt, iter::{Product, Sum}, num::FpCategory, - ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign}, + ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign}, }; macro_rules! forward_freeze_self { @@ -377,30 +377,6 @@ macro_rules! impls { Product, product, mul, Self::ONE, } - impl Neg for $fast_ty { - type Output = Self; - - #[inline(always)] - fn neg(self) -> Self::Output { - // Safety: - // - // - encountering poison is safe because LLVM's negate instruction documents - // not producing UB on any inputs. The value is also immediately wrapped, so - // poison propagation is controlled - let val = unsafe { self.0.maybe_poison() }; - $fast_ty::new(-val) - } - } - - impl Neg for &$fast_ty { - type Output = <$fast_ty as Neg>::Output; - - #[inline] - fn neg(self) -> Self::Output { - -(*self) - } - } - // Branching on poison values is UB, so any operation that makes a bool is protected by // freezing the operands. This includes [Partial]Eq and [Partial]Ord. Unfortunately // freezing has a nontrivial impact on performance, so non-bool methods should be preferred @@ -526,5 +502,3 @@ macro_rules! impls { impls! { FF32, f32 } impls! { FF64, f64 } - -// TODO num_traits, libm? diff --git a/src/math/math.c b/src/math/math.c index db6f9e5..7e035c0 100644 --- a/src/math/math.c +++ b/src/math/math.c @@ -23,6 +23,11 @@ } \ \ __attribute__((always_inline)) \ + C_TYPE neg_ ## RUST_TYPE(C_TYPE a) { \ + return -a; \ + } \ + \ + __attribute__((always_inline)) \ bool eq_ ## RUST_TYPE(C_TYPE a, C_TYPE b) { \ return a == b; \ } \ @@ -62,9 +67,11 @@ IMPL_OPERATIONS(float, f32) IMPL_OPERATIONS(double, f64) +// FIXME sqrt is not poison safe on some targets IMPL_UNARY_FUNCTION(float, f32, sqrt, sqrtf) IMPL_UNARY_FUNCTION(double, f64, sqrt, sqrt) +// FIXME mod is not poison safe, though LLVM frem is IMPL_BINARY_FUNCTION(float, f32, rem, fmodf) IMPL_BINARY_FUNCTION(double, f64, rem, fmod) diff --git a/src/math/mod.rs b/src/math/mod.rs index 8cef6bf..2a1dda1 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -1,5 +1,5 @@ use crate::{poison::MaybePoison, FF32, FF64}; -use core::ops::{Add, Div, Mul, Rem, Sub}; +use core::ops::{Add, Div, Mul, Neg, Rem, Sub}; use paste::paste; impl FF32 { @@ -152,6 +152,8 @@ macro_rules! impl_extern_math { fn [](a: $fast_ty, b: $fast_ty) -> $fast_ty; fn [](a: $fast_ty, b: $fast_ty) -> $fast_ty; + fn [](a: $fast_ty) -> $fast_ty; + fn [](a: $fast_ty, b: $fast_ty) -> $fast_ty; fn [](a: $fast_ty, b: $fast_ty) -> $fast_ty; @@ -167,6 +169,24 @@ macro_rules! impl_extern_math { Rem, rem, [], } + impl Neg for $fast_ty { + type Output = Self; + + #[inline(always)] + fn neg(self) -> Self::Output { + unsafe { [](self) } + } + } + + impl Neg for &$fast_ty { + type Output = <$fast_ty as Neg>::Output; + + #[inline] + fn neg(self) -> Self::Output { + -(*self) + } + } + impl $fast_ty { #[inline] pub fn max(self, other: Self) -> Self {