Add a constant for negative pi and provide a standalone const
`from_bits`, which can be combined with what we already had in
`hex_float`. Also provide another default method to reduce what needs to
be provided by the macro.
Add generic versions of `abs` and `copysign`, which will provide an
entrypoint for adding `f16` and `f128`. Since this implementation is
identical to the existing type-specific implementations, make use of it
for `f32` and `f64`.
The ambiguous associated types error sometimes fires in cases where it
shouldn't be ambiguous ([1]), which can make things clunky when working
with chained associated types (e.g. `Op::FTy::Int::*` does not work).
Add helper types that we can use instead of the full syntax.
There aren't too many cases in-crate now but this is relevant for some
open PRs.
[1]: https://github.com/rust-lang/rust/issues/38078
These were taken from `compiler-builtins` but the implementation has a
bug near the integer limits. Fixed in `compiler-builtins` by using
`core`'s implementation at [1], this is the corresponding fix for
`libm`.
[1]: https://github.com/rust-lang/compiler-builtins/pull/736
We now have tests against our custom-built musl as well as tests against
MPFR. The tests against system musl covers less than those against
custom-built musl, and are less portable; there isn't much benefit to
keeping them around so just remove them.
There are a handful of functions we can move out of the macro and to the
numeric traits as default implementations; do that here.
Additionally, add some bounds that make sense for completeness.
Currently there is a combination of names starting with
`multiprecision_`, `mp_` and `multiprec_`. Update so `multiprecision_`
is always used when a long form makes sense, `mp_` otherwise
(eliminating `multiprec_`).
This contains:
1. Per-function and per-operation enums created by the proc macro
2. The `MathOp` trait which is implemented once per struct representing
a function
3. Submodules for each function, each containing a `Routine` struct that
implements `MathOp`
Currently the macro always provides `CFn`, `RustFn`, `RustArgs`, etc.
Change this so that:
1. This information must be explicily requested in the invocation.
2. There is a new `FTy` field available that emits a single float type,
rather than a tuple or signature.
Additionally, add two new macros that create enums representing function
names.
Rust does not have any native way to parse hex floats, but they are
heavily used in the C algorithms that we derive from. Introduce a const
function that can parse these, as well as macros `hf32!` and `hf64!`
that ensure the string literals get handled at compiler time.
These are currently not used but making everything available now will
ease future development.
Co-authored-by: quaternic <57393910+quaternic@users.noreply.github.com>
This involves moving some things from full generic implementations (e.g.
`impl<F: Float> SomeTrait for F { /* ... */ }` to generic functions and
macros to implement traits that call them, due to orphan rule violations
after `Float` became a not-in-crate trait.
`Hex` was moved to `test_traits` so we can eliminate `num_traits`.
The test versions of `Float` and `Int` have a few more methods and
constants availablee. Update the in `libm` with everything missing from
`libm_test` so we will be able to merge these.
In preparation of adding generic algorithms to `libm`, add the traits
from `compiler-builtins`.
Eventually we should be able to unify the two crates so we don't have
duplicate implementations.
Introduce a Cargo feature to enable or disable architecture-specific
features (SIMD, assembly), which is on by default. This allows for more
fine grained control compared to relying on the `force-soft-floats`
feature.
Similar to "unstable-intrinsics", introduce a build.rs config option for
`unstable-intrinsics AND NOT force-soft-floats`, which makes this easier
to work with in code.
Effectively, this allows moving our non-additive Cargo feature
(force-soft-floats) to a positive one by default, allowing for an
override when needed.
`cfg_if` is helpful for applying `cfg` attributes to groups of items,
like we will need to do with architecture-specific modules of `f16` and
`f128`. However, `libm` can't have dependencies.
The `cfg_if` macro is complex but small, so just vendor it here.
Don't try to generate tests for directories, or for files that contain
`f16` or `f128` (as these types are not provided by musl's math
implementations).
(cherry picked from commit fd7ad36b70d0bbc0f0b9bc7e54d10258423fda29)