Commit Graph

949 Commits

Author SHA1 Message Date
Joshua Nelson
1a41e48d11 fix tests to work with --feature c 2023-06-27 02:31:42 +00:00
Joshua Nelson
e7c4a45348 require naked functions to be unsafe again
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.
2023-06-26 16:27:16 +00:00
Joshua Nelson
6242fd629e address review comments and fix CI
- implement CAS 16
- remove useless commented out symbol name
- support `feature("no-asm")`
- fix warnings when `feature("c")` is enabled
- rustfmt
2023-06-26 15:09:37 +00:00
Joshua Nelson
21c821c6c9 Port outline-atomics to rust
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.
2023-06-26 05:56:08 +00:00
Amanieu d'Antras
4a84991713
Merge pull request #529 from knickish/compile_warning_cleanup 2023-06-18 00:47:22 +02:00
kirk
fad0b3a431 change links in README to match reference code version used in CI 2023-06-17 14:35:00 +00:00
kirk
d3951c082e allow stable features lint, fix link formatting warning, add ignore block to intrinsics macro documentation 2023-06-17 14:11:31 +00:00
Amanieu d'Antras
2eeedaf25a Bump to 0.1.93 2023-06-12 15:37:22 +01:00
Patryk Wychowaniec
73f57893aa
fix: Add #[avr_skip] for floats
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.
2023-06-12 14:14:36 +02:00
Amanieu d'Antras
92d88fd7a4 Bump to 0.1.92 2023-05-20 10:50:12 +02:00
Amanieu d'Antras
2eb4f692bc Upgrade libm to 0.2.7 2023-05-20 10:49:41 +02:00
danakj
fb77604e79 Add the weak-intrinsics feature
When enabled, the weak-intrinsics feature will cause all intrinsics
functions to be marked with weak linkage (i.e. `#[linkage = "weak"])
so that they can be replaced at link time by a stronger symbol.

This can be set to use C++ intrinsics from the compiler-rt library,
as it will avoid Rust's implementation replacing the compiler-rt
implementation as long as the compiler-rt symbols are linked as
strong symbols. Typically this requires the compiler-rt library to
be explicitly specified in the link command.

Addresses https://github.com/rust-lang/compiler-builtins/issues/525.

Without weak-intrinsics, from nm:
```
00000000 W __aeabi_memclr8  // Is explicitly weak
00000000 T __udivsi3  // Is not.
```

With weak-intrinsics, from nm:
```
00000000 W __aeabi_memclr8  // Is explicitly weak
00000000 W __udivsi3  // Is weak due to weak-intrinsics
```
2023-05-19 17:35:00 -04:00
Amanieu d'Antras
7749ed6580 Bump to 0.1.91 2023-03-29 23:55:20 +01:00
William D. Jones
5246405d61 Ensure shift instrinsic arguments match width of compiler-rt's (int vs si_int). 2023-03-29 17:55:46 -04:00
Amanieu d'Antras
7db8c0581d Disable another test on powerpc 2023-03-29 21:49:08 +01:00
Amanieu d'Antras
26e2432c25 Bump to 0.1.90 2023-03-25 21:55:23 +00:00
Taiki Endo
2f43b93603 Fix panic due to overflow in riscv.rs and int/shift.rs 2023-03-23 22:00:22 +09:00
Amanieu d'Antras
da5001e4c6
Merge pull request #516 from TDecki/master 2023-03-12 22:17:23 +01:00
Amanieu d'Antras
20fb963ab6 Add emutls.c for OpenHarmony 2023-03-10 19:59:23 +00:00
Tobias Decking
59766673e7
more fixing 2023-03-06 19:28:49 +01:00
Tobias Decking
73fa0deaa6
formatting 2023-03-06 19:24:02 +01:00
Tobias Decking
215f63ad19
Final version. 2023-03-06 19:20:30 +01:00
Andrew Kane
59fb34e63a Added lgamma_r and lgammaf_r 2023-03-05 12:17:21 -08:00
Amanieu d'Antras
3e59619de7 Bump to 0.1.88 2023-02-23 18:19:41 +00:00
Tobias Decking
04fe482160
Formatting 2023-02-22 22:19:10 +01:00
Tobias Decking
c7404df069
Provide a non-sse version for x86_64. 2023-02-22 22:16:29 +01:00
Scott Mabin
67ebc4ae14 Extend the intrinsics exported for Xtensa no_std 2023-02-22 20:56:31 +00:00
Tobias Decking
97402fc580
Change implementation to SSE 2023-02-22 21:54:33 +01:00
Tobias Decking
e9e34801a6
Remove superfluous comment. 2023-02-22 00:10:46 +01:00
Tobias Decking
b53c1ae17a
Improve assembly quality + AT&T syntax. 2023-02-22 00:07:41 +01:00
Tobias Decking
44d34e87fa
Update path for argument. 2023-02-21 23:36:47 +01:00
Tobias Decking
990596fa28
Correct path. 2023-02-21 23:32:39 +01:00
Tobias Decking
a11bd1cfdb
Specialize strlen for x86_64. 2023-02-21 23:13:02 +01:00
Amanieu d'Antras
2ca64c2798 Bump to 0.1.87 2023-02-03 19:21:40 +01:00
Josh Stone
8d4e906206 Drop the llvm14-builtins-abi hack 2023-02-01 14:52:18 -08:00
Amanieu d'Antras
7f39126ff9 Bump to 0.1.86 2022-12-29 20:36:57 +01:00
Patryk Wychowaniec
d20eea4d47
fix: Add #[avr_skip] for bit shifts
This commit follows the same logic as:

- https://github.com/rust-lang/compiler-builtins/pull/462
- https://github.com/rust-lang/compiler-builtins/pull/466

I've tested the changes by preparing a simple program:

```rust
fn calc() -> ... {
    let x = hint::black_box(4u...); // 4u8, 4u16, 4u32, 4u64, 4u128 + signed
    let y = hint::black_box(1u32);

    // x >> y
    // x << y
}

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);

    for b in calc().to_le_bytes() {
        _ = ufmt::uwrite!(&mut serial, "{} ", b);
    }

    _ = ufmt::uwriteln!(&mut serial, "");

    loop {
        //
    }
}
```

... switching types & operators in `calc()`, and observing the results;
what I ended up with was:

```
 u32 << u32 - ok
 u64 << u32 - ok
u128 << u32 - error (undefined reference to `__ashlti3')
 i32 >> u32 - ok
 i64 >> u32 - ok
i128 >> u32 - error (undefined reference to `__ashrti3')
 u32 >> u32 - ok
 u64 >> u32 - ok
u128 >> u32 - error (undefined reference to `__lshrti3')

(where "ok" = compiles and returns correct results)
```

As with multiplication and division, so do in here 128-bit operations
not work, because avr-gcc's standard library doesn't provide them (at
the same time, requiring that specific calling convention, making it
pretty difficult for compiler-builtins to jump in).

I think 128-bit operations non-working on an 8-bit controller is an
acceptable trade-off - 😇 - and so the entire fix in here is
just about skipping those functions.
2022-12-25 11:46:30 +01:00
Amanieu d'Antras
62cd3780ae Bump to 0.1.85 2022-12-08 13:31:59 +00:00
Martin Kröning
620f50589e Expose minimal floating point symbols for x86_64-unknown-none 2022-12-07 16:08:01 +01:00
Jérome Eertmans
80828bfb0b
fix(docs): typo in docstrings
Hello, I think you misspelled `width` to `with`.
2022-11-28 10:53:42 +01:00
Amanieu d'Antras
ad4ab99a2e Bump to 0.1.84 2022-11-18 02:58:11 +00:00
Nicholas Bishop
ebaca42a41 Use a stub stdlib.h when compiling for UEFI targets
int_util.c includes stdlib.h if `_WIN32` is defined. When compiling
the UEFI targets with clang they are treated as Windows targets (e.g. if
the Rust target is x86_64-unknown-uefi, the clang target is
x86_64-unknown-windows-gnu). So stdlib.h gets included, even though we
are compilling with `-ffreestanding` and don't want stdlib.h to be
used. That file may not be present, or an incompatible version might be
installed leading to typedef redefinition errors.

The contents of stdlib.h aren't actually needed for these targets anyway
(due to `__STDC_HOSTED__` being 0), so create a minimal stdlib.h in
`build.rs` when `target_os == uefi` and add it to the include path.
2022-11-17 21:16:01 -05:00
Amanieu d'Antras
371a6856ee
Merge pull request #504 from nicholasbishop/bishop-no-uefi-asm 2022-11-16 19:05:16 +00:00
Nicholas Bishop
98b3454d3d Skip assembly implementations on the UEFI targets
The UEFI targets link with `/SAFESEH`. That requires that objects have a
symbol called [`@feat.00`]. Clang adds that symbol for COFF targets if
the input is a C file, but not if the input is an ASM file. That doesn't
prevent compiler_builtins or rustc from building, but using the
resulting rustc to compile something that references one of the objects
lacking `@feat.00` will result in a linker error.

Fix by removing all the `.S` implementations when `target_os == uefi`.

[`@feat.00`]: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#the-sxdata-section
2022-11-16 13:16:42 -05:00
Nicholas Bishop
524ca7ceb6 Remove unused no-lang-items feature 2022-11-12 12:09:06 -05:00
Amanieu d'Antras
a996f56f5a Bump to 0.1.83 2022-11-09 04:12:51 +00:00
Jules Bertholet
af5664be84
Update libm, add rint and rintf 2022-11-08 21:04:02 -05:00
Felix S. Klock II
2faf57c08d might as well add the link to the LLVM assembly code as well. 2022-10-25 12:32:41 -04:00
Felix S. Klock II
8266a1343b Document origins of the multiplication method being used here. 2022-10-25 11:25:14 -04:00
Amanieu d'Antras
6f53a4f074 Bump to 0.1.82 2022-10-10 19:04:06 +01:00