Removed the `weak-intrinsics` feature, so that all functions
will have the `weak` linkage attribute.
Also this fixed the bug in
https://github.com/rust-lang/rust/issues/124042.
Before this commit, generated code will be
```rust
pub extern "C" fn <name>(...) -> ... {
// code...
}
pub mod <name> {
#[linkage = "weak"]
#[no_mangle]
pub extern "C" fn <name>(...) -> ... {
super::<name>(...)
}
}
```
The issue is that there is 2 `weak` linkage, the first one is not required.
Along refactoring `weak` attributes, this was fixed.
This is a continuation/fix of 018616e. In that commit, we made it add
the math functions to all platforms (except apple-targets and windows),
and use `weak` linking, so that it can be used if the system doesn't
have those functions.
Didn't notice `mod math` was behind another set of `cfg`, so removed it
as well here.
The Apple ARM silicon has been around for a while now and hopefully will
become Rust Tier 1 at some point. Add it to CI since it is distinct
enough from aarch64-linux and x86_86-darwin that there may be
differences.
Trying to run testcrate on non-linux aarch64 currently hits a
compilation error. Make this test linux-only, to be consistent with the
`aarch64_linux` module that it depends on.
Additionally, enable the `aarch64_linux` module for `target_arch =
"arm64ec"` to be the same as these tests.
This is a replacement for https://github.com/rust-lang/libm/pull/290
This fixes crashes during compilations for targets that don't have math
symbols by default.
So, we will provide them libm symbols, but mark it as `weak` (if its
supported), so that the linker will choose the system builtin functions,
since those are sometimes more optimized.
If the linker couldn't find those, it will go with `libm`
implementation.
libLLVMSupport.a(DynamicLibrary.cpp.obj) references ___chkstk, which is
an alias of __alloca in libgcc. This crate provided __alloca, but
libgcc's implementation was also pulled in by the linker due to the
reference to ___chkstk, causing a multiple definition linker error.
Providing that symbol here prevents that.
Fixes#585
It turns out that these also don't build on x86 + MSVC. Rather
than fixing up the condition, I'm just deleting them entirely.
As far as I know, Rust does not support 80-bit floats and has
no plan to support them, so we shouldn't need them.
Tale as old as the world - there's an ABI mismatch:
https://github.com/rust-lang/compiler-builtins/pull/527
Fortunately, newest GCCs (from v11, it seems) actually provide most of
those intrinsics (even for f64!), so that's pretty cool.
(the only intrinsics not provided by GCC are `__powisf2` & `__powidf2`,
but our codegen for AVR doesn't emit those anyway.)
Fixes https://github.com/rust-lang/rust/issues/118079.
Like SGX, Xous does not have any libc to link against. As a result,
memory intrinsics need to be available as part of `compiler_builtins`
Signed-off-by: Sean Cross <sean@xobs.io>
they dereference raw pointers, so the caller needs to make sure the
pointer is valid.
note that this requires changing `maybe_use_optimized_c_shim` to support
unsafe functions.
This has a very long history, summarized in
https://github.com/rust-lang/rust/issues/109064. This port is a very
minimal subset of `aarch64/lse.S` from LLVM's compiler-rt. In
particular, it is missing the following:
1. Any form of runtime dispatch between LL/SC and LSE.
Determining which version of the intrinsics to use
requires one of the following:
i) `getauxval` from glibc. It's unclear whether `compiler_builtins` is
allowed to depend on libc at all, and musl doesn't even support
getauxval. Don't enshrine the requirement "de-facto" by making it
required for outline-atomics.
ii) kernel support. Linux and FreeBSD have limited support, but it
requires an extremely recent kernel version and doesn't work at all under QEMU (https://github.com/rust-lang/rust/issues/109064#issuecomment-1494939904).
Instead, we hard-code LL/SC intrinsics. Users who want LSE support
should use the LLVM compiler-rt (if you're building from source in
rust-lang/rust, make sure you have `src/llvm-project` checked out
locally. the goal is to soon add a new `optimized-compiler-builtins`
option so this is easier to discover).
2. The global `___aarch64_have_lse_atomics` CTOR, required to do runtime
dispatch. Thom Chiviolani has this to say about global CTORs:
> static ctors are problems because we are pretty eager about dead code elim
> in general if you have a module that isnt directly reference we will probably not have its static ctors
> also, while llvm has a super robust way to have a static ctor (theres s special "appending global" to use for c++), we dont use that and just have people make a #[used] static in a special section
> 1. the robust way kinda requires rust knowing that the argument is a static ctor (maybe a #[rustc_static_ctor] attribute). it also would be... finnicky, since on windows we actually care beyond being a static ctor, that we run as part in a specific group of ctors, which means a very specific section (one for TLS and the other for, uh, i dont remember)
> 2. we still actually have to codegen the cgu that isn't referenced. but maybe we could remember that it has that attribute and use that
So while this is possible in theory, it's decidedly non-trivial, and
needs invasive changes to rust itself. In any case, it doesn't matter
until we decide the story around libc.
3. The 16-byte (i128) version of compare_and_swap. This wouldn't be
*too* hard to add, but it would be hard to test. The way I tested the
existing code was not just with unit tests but also by loading it as a
path dependency and running `x test core` - the latter caught several
bugs the unit tests didn't catch (because I originally wrote the tests
wrong). So I am slightly nervous about adding a 16-byte version that is
much more poorly tested than the other intrinsics.
Same story as always, i.e. ABI mismatch:
- https://github.com/rust-lang/compiler-builtins/pull/462
- https://github.com/rust-lang/compiler-builtins/pull/466
- https://github.com/rust-lang/compiler-builtins/pull/513
I've made sure the changes work by rendering a Mandelbrot fractal:
```rust
#[arduino_hal::entry]
fn main() -> ! {
let dp = arduino_hal::Peripherals::take().unwrap();
let pins = arduino_hal::pins!(dp);
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);
mandelbrot(&mut serial, 60, 40, -2.05, -1.12, 0.47, 1.12, 100);
loop {
//
}
}
fn mandelbrot<T>(
output: &mut T,
viewport_width: i64,
viewport_height: i64,
x1: f32,
y1: f32,
x2: f32,
y2: f32,
max_iterations: i64,
) where
T: uWrite,
{
for viewport_y in 0..viewport_height {
let y0 = y1 + (y2 - y1) * ((viewport_y as f32) / (viewport_height as f32));
for viewport_x in 0..viewport_width {
let x0 = x1 + (x2 - x1) * ((viewport_x as f32) / (viewport_width as f32));
let mut x = 0.0;
let mut y = 0.0;
let mut iterations = max_iterations;
while x * x + y * y <= 4.0 && iterations > 0 {
let xtemp = x * x - y * y + x0;
y = 2.0 * x * y + y0;
x = xtemp;
iterations -= 1;
}
let ch = "#%=-:,. "
.chars()
.nth((8.0 * ((iterations as f32) / (max_iterations as f32))) as _)
.unwrap();
_ = ufmt::uwrite!(output, "{}", ch);
}
_ = ufmt::uwriteln!(output, "");
}
}
```
... where without avr_skips, the code printed an image full of only `#`.
Note that because libgcc doesn't provide implementations for f64, using
those (e.g. swapping f32 to f64 in the code above) will cause linking to
fail:
```
undefined reference to `__divdf3'
undefined reference to `__muldf3'
undefined reference to `__gedf2'
undefined reference to `__fixunsdfsi'
undefined reference to `__gtdf2'
```
Ideally compiler-builtins could jump right in and provide those, but f64
also require a special calling convention which hasn't been yet exposed
through LLVM.
Note that because using 64-bit floats on an 8-bit target is a pretty
niche thing to do, and because f64 floats don't work correctly anyway at
the moment (due to this ABI mismatch), we're not actually breaking
anything by skipping those functions, since any code that currently uses
f64 on AVR works by accident.
Closes https://github.com/rust-lang/rust/issues/108489.