1. Avoid undefined references as:
undefined reference to `__modsi3'
undefined reference to `__umodsi3'
2. We can't remove assembly implementations that are not in the list
Collection of VFP intrinsics
Nothing really exciting here, just a list of trivial VFP intrinsics.
First of all set `mfloat-abi=hard` not only for thumb targets, then add support for the following intrinsics:
```
__gesf2vfp
__gedf2vfp
__gtsf2vfp
__gtdf2vfp
__ltsf2vfp
__ltdf2vfp
__nesf2vfp
__nedf2vfp
__eqsf2vfp
__eqdf2vfp
__extendsfdf2vfp
```
Resulting implementation is really trivial thanks to native code generated by LLVM on hard-float targets
Fix issue extending f32::MIN/MAX to f64 and improve testcrate.
I was able to trigger an issue extending f32::MAX or f32::MIN to a f64.
Issue was **not** triggered by `testcrate` mainly because f32::MAX/MIN are
not in the list of special values to generate.
This PR fix the issue and improve `testcrate` adding MAX/MIN/MIN_POSITIVE
in the list of special values.
Be sure to do not mix hard-float and soft-float calls.
Disassembled code show exactly this.
So replace add with an explicit call to __addsf3/__adddf3
This seems the root cause of some sporadic failures.
I was able to trigger an issue extending f32::MAX or f32::MIN to a f64.
Issue was not triggered by `testcrate` mainly because f32::MAX/MIN are
not in the list of special values to generate.
This PR fix the issue and improve `testcrate` adding MAX/MIN/MIN_POSITIVE
in the list of special values.
Add generic conversion from a narrower to a wider FP type
Add `extend` module to implement conversion from a narrower to a wider floating-point type.
This implementation is only intended to support *widening* operations.
Module to convert a *narrower* floating-point will be added in the future.
Add `extend` module to implement conversion from a narrower to a wider
floating-point type.
This implementation is only intended to support *widening* operations.
Module to convert a *narrower* floating-point will be added in the future.
Add support for sub*f3vfp and add*f3vfp
As done before for `mul` and `div` let's use extern "C" to generate `"aapcs"` or `"aapcs-vfp"` depending on target configuration.
All tests are moved to a separate crate in this repository to enable features by
default. Additionally the test generation is moved to a seprate build script and
simplified to reduce the amount of boilerplate needed per test.
Overall this should still be testing everything, just in a different location!
Here using `"C"` the compiler will use `"aapcs"` or `"aapcs-vfp"`
depending on target configuration.
Of course this translates in a call to `__aeabi_fdiv` / `__aeabi_fmul`
on non-HF targets.
On `eabi` targets with +vfpv2/vfpv3 LLVM generate:
vmov s0, r1
vmov s2, r0
vdiv.f32 s0, s2, s0
vmov r0, s0
bx lr
On `eabihf` targets with +vfpv3-d16/d32/f32 +fp-only-sp LLVM generate:
vdiv.f32 s0, s0, s1
bx lr
That's exactly what We need for [div/mul][s/d]f3vfp.S
* I believe `__gtdf2` erroneously used `f32` instead of `f64`
* Most of these needed `#[arm_aeabi_alias]` to ensure they're correctly called
through the alias
* Some existing aliases were corrected with the right names
First of all aeabi_cdcmp and aeabi_cfcmp are never called LLVM.
Second are little-endian only, so build fail on big-endian targets.
Temporally workaround: exclude these files for big-endian targets.
Note that this changes semantics:
pub extern "C" fn __eqsf2(a: f32, b: f32) -> bool {
cmp(a, b).to_le_abi() != 0
}
is not the same as
pub extern "C" fn __eqsf2(a: f32, b: f32) -> i32 {
cmp(a, b).to_le_abi()
}
However, compiler-rt does the latter, so this is actually
an improvement.
E.g. take a look at the assembly output for:
pub fn comparesf2(a: f32, b: f32) -> bool { a > b }
pub fn comparedf2(a: f64, b: f64) -> bool { a > b }
which will include calls to __gtsf2 and __gtdf2.