Skip to content

Commit c2d680f

Browse files
committed
Update README and CONTRIBUTING for the new repository layout
1 parent d3abeaf commit c2d680f

File tree

6 files changed

+213
-158
lines changed

6 files changed

+213
-158
lines changed

CONTRIBUTING.md

+137-52
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,167 @@
11
# How to contribute
22

3-
- Pick your favorite math function from the [issue tracker].
4-
- Look for the C implementation of the function in the [MUSL source code][src].
5-
- Copy paste the C code into a Rust file in the `src/math` directory and adjust
6-
`src/math/mod.rs` accordingly. Also, uncomment the corresponding trait method
7-
in `src/lib.rs`.
8-
- Write some simple tests in your module (using `#[test]`)
9-
- Run `cargo test` to make sure it works. Full tests are only run when enabling
10-
features, see [Testing](#testing) below.
11-
- Send us a pull request! Make sure to run `cargo fmt` on your code before
12-
sending the PR. Also include "closes #42" in the PR description to close the
13-
corresponding issue.
14-
- :tada:
15-
16-
[issue tracker]: https://github.com/rust-lang/libm/issues
17-
[src]: https://git.musl-libc.org/cgit/musl/tree/src/math
18-
[`src/math/truncf.rs`]: https://github.com/rust-lang/libm/blob/master/src/math/truncf.rs
19-
20-
Check [PR #65] for an example.
21-
22-
[PR #65]: https://github.com/rust-lang/libm/pull/65
3+
## compiler-builtins
4+
5+
1. From the [pending list](compiler-builtins/README.md#progress), pick one or
6+
more intrinsics.
7+
2. Port the version from [`compiler-rt`] and, if applicable, their
8+
[tests][rt-tests]. Note that this crate has generic implementations for a lot
9+
of routines, which may be usable without porting the entire implementation.
10+
3. Add a test to `builtins-test`, comparing the behavior of the ported
11+
intrinsic(s) with their implementation on the testing host.
12+
4. Add the intrinsic to `builtins-test-intrinsics/src/main.rs` to verify it can
13+
be linked on all targets.
14+
5. Send a Pull Request (PR) :tada:.
15+
16+
[`compiler-rt`]: https://github.com/llvm/llvm-project/tree/b6820c35c59a4da3e59c11f657093ffbd79ae1db/compiler-rt/lib/builtins
17+
[rt-tests]: https://github.com/llvm/llvm-project/tree/b6820c35c59a4da3e59c11f657093ffbd79ae1db/compiler-rt/test/builtins
18+
19+
## Porting Reminders
20+
21+
1. [Rust][prec-rust] and [C][prec-c] have slightly different operator
22+
precedence. C evaluates comparisons (`== !=`) before bitwise operations
23+
(`& | ^`), while Rust evaluates the other way.
24+
2. C assumes wrapping operations everywhere. Rust panics on overflow when in
25+
debug mode. Consider using the [Wrapping][wrap-ty] type or the explicit
26+
[wrapping_*][wrap-fn] functions where applicable.
27+
3. Note [C implicit casts][casts], especially integer promotion. Rust is much
28+
more explicit about casting, so be sure that any cast which affects the
29+
output is ported to the Rust implementation.
30+
4. Rust has [many functions][i32] for integer or floating point manipulation in
31+
the standard library. Consider using one of these functions rather than
32+
porting a new one.
33+
34+
[prec-rust]: https://doc.rust-lang.org/reference/expressions.html#expression-precedence
35+
[prec-c]: http://en.cppreference.com/w/c/language/operator_precedence
36+
[wrap-ty]: https://doc.rust-lang.org/core/num/struct.Wrapping.html
37+
[wrap-fn]: https://doc.rust-lang.org/std/primitive.i32.html#method.wrapping_add
38+
[casts]: http://en.cppreference.com/w/cpp/language/implicit_conversion
39+
[i32]: https://doc.rust-lang.org/std/primitive.i32.html
2340

2441
## Tips and tricks
2542

26-
- *IMPORTANT* The code in this crate will end up being used in the `core` crate so it can **not**
27-
have any external dependencies (other than `core` itself).
28-
29-
- Only use relative imports within the `math` directory / module, e.g. `use self::fabs::fabs` or
30-
`use super::k_cos`. Absolute imports from core are OK, e.g. `use core::u64`.
31-
32-
- To reinterpret a float as an integer use the `to_bits` method. The MUSL code uses the
33-
`GET_FLOAT_WORD` macro, or a union, to do this operation.
34-
35-
- To reinterpret an integer as a float use the `f32::from_bits` constructor. The MUSL code uses the
36-
`SET_FLOAT_WORD` macro, or a union, to do this operation.
37-
43+
- _IMPORTANT_ The code in this crate will end up being used in the `core` crate
44+
so it can **not** have any external dependencies (other than a subset of
45+
`core` itself).
46+
- Only use relative imports within the `math` directory / module, e.g.
47+
`use self::fabs::fabs` or `use super::k_cos`. Absolute imports from core are
48+
OK, e.g. `use core::u64`.
49+
- To reinterpret a float as an integer use the `to_bits` method. The MUSL code
50+
uses the `GET_FLOAT_WORD` macro, or a union, to do this operation.
51+
- To reinterpret an integer as a float use the `f32::from_bits` constructor. The
52+
MUSL code uses the `SET_FLOAT_WORD` macro, or a union, to do this operation.
3853
- You may use other methods from core like `f64::is_nan`, etc. as appropriate.
39-
40-
- If you're implementing one of the private double-underscore functions, take a look at the
41-
"source" name in the comment at the top for an idea for alternate naming. For example, `__sin`
42-
was renamed to `k_sin` after the FreeBSD source code naming. Do `use` these private functions in
43-
`mod.rs`.
44-
45-
- You may encounter weird literals like `0x1p127f` in the MUSL code. These are hexadecimal floating
46-
point literals. Rust (the language) doesn't support these kind of literals. This crate provides
47-
two macros, `hf32!` and `hf64!`, which convert string literals to floats at compile time.
54+
- Rust does not have hex float literals. This crate provides two `hf16!`,
55+
`hf32!`, `hf64!`, and `hf128!` which convert string literals to floats at
56+
compile time.
4857

4958
```rust
5059
assert_eq!(hf32!("0x1.ffep+8").to_bits(), 0x43fff000);
5160
assert_eq!(hf64!("0x1.ffep+8").to_bits(), 0x407ffe0000000000);
5261
```
5362

54-
- Rust code panics on arithmetic overflows when not optimized. You may need to use the [`Wrapping`]
55-
newtype to avoid this problem, or individual methods like [`wrapping_add`].
63+
- Rust code panics on arithmetic overflows when not optimized. You may need to
64+
use the [`Wrapping`] newtype to avoid this problem, or individual methods like
65+
[`wrapping_add`].
5666

5767
[`Wrapping`]: https://doc.rust-lang.org/std/num/struct.Wrapping.html
5868
[`wrapping_add`]: https://doc.rust-lang.org/std/primitive.u32.html#method.wrapping_add
5969

6070
## Testing
6171

62-
Normal tests can be executed with:
72+
Testing for these crates can be somewhat complex, so feel free to rely on CI.
73+
74+
The easiest way replicate CI testing is using Docker. This can be done by
75+
running `./ci/run-docker.sh [target]`. If no target is specified, all targets
76+
will be run.
77+
78+
Tests can also be run without Docker:
6379

6480
```sh
65-
# Tests against musl require that the submodule is up to date.
81+
# Run basic tests
82+
#
83+
# --no-default-features always needs to be passed, an unfortunate limitation
84+
# since the `#![compiler_builtins]` feature is enabled by default.
85+
cargo test --workspace --no-default-features
86+
87+
# Test with all interesting features
88+
cargo test --workspace --no-default-features \
89+
--features arch,unstable-float,unstable-intrinsics,mem
90+
91+
# Run with more detailed tests for libm
92+
cargo test --workspace --no-default-features \
93+
--features arch,unstable-float,unstable-intrinsics,mem \
94+
--features build-mpfr,build-musl \
95+
--profile release-checked
96+
```
97+
98+
The multiprecision tests use the [`rug`] crate for bindings to MPFR. MPFR can be
99+
difficult to build on non-Unix systems, refer to [`gmp_mpfr_sys`] for help.
100+
101+
`build-musl` does not build with MSVC, Wasm, or Thumb.
102+
103+
[`rug`]: https://docs.rs/rug/latest/rug/
104+
[`gmp_mpfr_sys`]: https://docs.rs/gmp-mpfr-sys/1.6.4/gmp_mpfr_sys/
105+
106+
In order to run all tests, some dependencies may be required:
107+
108+
```sh
109+
# Allow testing compiler-builtins
110+
./ci/download-compiler-rt.sh
111+
112+
# Optional, initialize musl for `--features build-musl`
66113
git submodule init
67114
git submodule update
68115

69116
# `--release` ables more test cases
70117
cargo test --release
71118
```
72119

73-
If you are on a system that cannot build musl or MPFR, passing
74-
`--no-default-features` will run some limited tests.
120+
### Extensive tests
75121

76-
The multiprecision tests use the [`rug`] crate for bindings to MPFR. MPFR can
77-
be difficult to build on non-Unix systems, refer to [`gmp_mpfr_sys`] for help.
122+
Libm also has tests that are exhaustive (for single-argument `f32` and 1- or 2-
123+
argument `f16`) or extensive (for all other float and argument combinations).
124+
These take quite a long time to run, but are launched in CI when relevant files
125+
are changed.
78126

79-
`build-musl` does not build with MSVC, Wasm, or Thumb.
127+
Exhaustive tests can be selected by passing an environment variable:
80128

81-
[`rug`]: https://docs.rs/rug/latest/rug/
82-
[`gmp_mpfr_sys`]: https://docs.rs/gmp-mpfr-sys/1.6.4/gmp_mpfr_sys/
129+
```sh
130+
LIBM_EXTENSIVE_TESTS=sqrt,sqrtf cargo test --features build-mpfr \
131+
--test z_extensive \
132+
--profile release-checked
133+
134+
# Run all tests for one type
135+
LIBM_EXTENSIVE_TESTS=all_f16 cargo test ...
136+
137+
# Ensure `f64` tests can run exhaustively. Estimated completion test for a
138+
# single test is 57306 years on my machine so this may be worth skipping.
139+
LIBM_EXTENSIVE_TESTS=all LIBM_EXTENSIVE_ITERATIONS=18446744073709551615 cargo test ...
140+
```
141+
142+
## Benchmarking
143+
144+
Regular walltime benchmarks can be run with `cargo bench`:
145+
146+
```sh
147+
cargo bench --no-default-features \
148+
--features arch,unstable-float,unstable-intrinsics,mem \
149+
--features benchmarking-reports
150+
```
151+
152+
There are also benchmarks that check instruction count behind the `icount`
153+
feature. These require [`iai-callgrind-runner`] (via Cargo) and [Valgrind]
154+
to be installed, which means these only run on limited platforms.
155+
156+
Instruction count benchmarks are run as part of CI to flag performance
157+
regresions.
158+
159+
```sh
160+
cargo bench --no-default-features \
161+
--features arch,unstable-float,unstable-intrinsics,mem \
162+
--features icount \
163+
--bench icount --bench mem_icount
164+
```
165+
166+
[`iai-callgrind-runner`]: https://crates.io/crates/iai-callgrind-runner
167+
[Valgrind]: https://valgrind.org/

README.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# `compiler-builtins` and `libm`
2+
3+
This repository contains two main crates:
4+
5+
* `compiler-builtins`: symbols that the compiler expects to be available at
6+
link time
7+
* `libm`: a Rust implementation of C math libraries, used to provide
8+
implementations in `ocre`.
9+
10+
More details are at [compiler-builtins/README.md](compiler-builtins/README.md)
11+
and [libm/README.md](libm/README.md).
12+
13+
For instructions on contributing, see [CONTRIBUTING.md](CONTRIBUTING.md).
14+
15+
## License
16+
17+
* `libm` may be used under the [MIT License]
18+
* `compiler-builtins` may be used under the [MIT License] and the
19+
[Apache License, Version 2.0] with the LLVM exception.
20+
* All original contributions must be under all of: the MIT license, the
21+
Apache-2.0 license, and the Apache-2.0 license with the LLVM exception.
22+
23+
More details are in [LICENSE.txt](LICENSE.txt) and
24+
[libm/LICENSE.txt](libm/LICENSE.txt).
25+
26+
[MIT License]: https://opensource.org/license/mit
27+
[Apache License, Version 2.0]: htps://www.apache.org/licenses/LICENSE-2.0

compiler-builtins/Cargo.toml

+10-13
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,21 @@ authors = ["Jorge Aparicio <[email protected]>"]
33
name = "compiler_builtins"
44
version = "0.1.155"
55
license = "MIT AND Apache-2.0 WITH LLVM-exception AND (MIT OR Apache-2.0)"
6-
readme = "../README.md"
6+
readme = "README.md"
77
repository = "https://github.com/rust-lang/compiler-builtins"
88
homepage = "https://github.com/rust-lang/compiler-builtins"
99
documentation = "https://docs.rs/compiler_builtins"
1010
edition = "2021"
11-
description = """
12-
Compiler intrinsics used by the Rust compiler. Also available for other targets
13-
if necessary!
14-
"""
11+
description = "Compiler intrinsics used by the Rust compiler."
1512
include = [
16-
'/Cargo.toml',
17-
'/build.rs',
18-
'/configure.rs',
19-
'/src/*',
20-
'../LICENSE.txt',
21-
'../compiler-rt/*',
22-
'README.md',
23-
'libm/src/math/*',
13+
"../LICENSE.txt",
14+
"../compiler-rt/*",
15+
"/Cargo.toml",
16+
"/build.rs",
17+
"/configure.rs",
18+
"/src/*",
19+
"README.md",
20+
"libm/src/math/*",
2421
]
2522
links = 'compiler-rt'
2623

compiler-builtins/README.md

+18-58
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,18 @@
11
# `compiler-builtins`
22

3-
This crate provides external symbols that the compiler expects to be available when
4-
building Rust projects, typically software routines for basic operations that do not
5-
have hardware support. It is largely a port of LLVM's [`compiler-rt`].
3+
This crate provides external symbols that the compiler expects to be available
4+
when building Rust projects, typically software routines for basic operations
5+
that do not have hardware support. It is largely a port of LLVM's
6+
[`compiler-rt`].
67

7-
It is distributed as part of Rust's sysroot.
8+
It is distributed as part of Rust's sysroot. `compiler-builtins` does not need
9+
to be added as an explicit dependency in `Cargo.toml`.
810

911
[`compiler-rt`]: https://github.com/llvm/llvm-project/tree/1b1dc505057322f4fa1110ef4f53c44347f52986/compiler-rt
1012

1113
## Contributing
1214

13-
1. Pick one or more intrinsics from the [pending list](#progress).
14-
2. Fork this repository.
15-
3. Port the intrinsic(s) and their corresponding [unit tests][1] from their
16-
[C implementation][2] to Rust.
17-
4. Add a test to compare the behavior of the ported intrinsic(s) with their
18-
implementation on the testing host.
19-
5. Add the intrinsic to `builtins-test-intrinsics/src/main.rs` to verify it
20-
can be linked on all targets.
21-
6. Send a Pull Request (PR).
22-
7. Once the PR passes our extensive testing infrastructure, we'll merge it!
23-
8. Celebrate :tada:
24-
25-
[1]: https://github.com/rust-lang/llvm-project/tree/9e3de9490ff580cd484fbfa2908292b4838d56e7/compiler-rt/test/builtins/Unit
26-
[2]: https://github.com/rust-lang/llvm-project/tree/9e3de9490ff580cd484fbfa2908292b4838d56e7/compiler-rt/lib/builtins
27-
[3]: https://github.com/rust-lang/compiler-builtins/actions
28-
29-
### Porting Reminders
30-
31-
1. [Rust][5a] and [C][5b] have slightly different operator precedence. C evaluates comparisons (`== !=`) before bitwise operations (`& | ^`), while Rust evaluates the other way.
32-
2. C assumes wrapping operations everywhere. Rust panics on overflow when in debug mode. Consider using the [Wrapping][6] type or the explicit [wrapping_*][7] functions where applicable.
33-
3. Note [C implicit casts][8], especially integer promotion. Rust is much more explicit about casting, so be sure that any cast which affects the output is ported to the Rust implementation.
34-
4. Rust has [many functions][9] for integer or floating point manipulation in the standard library. Consider using one of these functions rather than porting a new one.
35-
36-
[5a]: https://doc.rust-lang.org/reference/expressions.html#expression-precedence
37-
[5b]: http://en.cppreference.com/w/c/language/operator_precedence
38-
[6]: https://doc.rust-lang.org/core/num/struct.Wrapping.html
39-
[7]: https://doc.rust-lang.org/std/primitive.i32.html#method.wrapping_add
40-
[8]: http://en.cppreference.com/w/cpp/language/implicit_conversion
41-
[9]: https://doc.rust-lang.org/std/primitive.i32.html
42-
43-
## Testing
44-
45-
The easiest way to test locally is using Docker. This can be done by running
46-
`./ci/run-docker.sh [target]`. If no target is specified, all targets will be
47-
run.
48-
49-
In order to run the full test suite, you will also need the C compiler runtime
50-
to test against, located in a directory called `compiler-rt`. This can be
51-
obtained with the following:
52-
53-
```sh
54-
curl -L -o rustc-llvm-20.1.tar.gz https://github.com/rust-lang/llvm-project/archive/rustc/20.1-2025-02-13.tar.gz
55-
tar xzf rustc-llvm-20.1.tar.gz --strip-components 1 llvm-project-rustc-20.1-2025-02-13/compiler-rt
56-
```
57-
58-
Local targets may also be tested with `./ci/run.sh [target]`.
59-
60-
Note that testing may not work on all hosts, in which cases it is acceptable to
61-
rely on CI.
15+
See [CONTRIBUTING.md](CONTRIBUTING.md).
6216

6317
## Progress
6418

@@ -468,9 +422,15 @@ Unsupported in any current target: used on old versions of 32-bit iOS with ARMv5
468422

469423
## License
470424

471-
The compiler-builtins crate is dual licensed under both the University of
472-
Illinois "BSD-Like" license and the MIT license. As a user of this code you may
473-
choose to use it under either license. As a contributor, you agree to allow
474-
your code to be used under both.
425+
Usage is allowed under the [MIT License] and the [Apache License, Version 2.0]
426+
with the LLVM exception.
427+
428+
[MIT License]: https://opensource.org/license/mit
429+
[Apache License, Version 2.0]: htps://www.apache.org/licenses/LICENSE-2.0
430+
431+
### Contribution
432+
433+
Contributions are licensed under the MIT License, the Apache License,
434+
Version 2.0, and the Apache-2.0 license with the LLVM exception.
475435

476-
Full text of the relevant licenses is in LICENSE.TXT.
436+
See [LICENSE.txt](../LICENSE.txt) for full details.

libm/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ keywords = ["libm", "math"]
77
license = "MIT"
88
name = "libm"
99
readme = "README.md"
10-
repository = "https://github.com/rust-lang/libm"
10+
repository = "https://github.com/rust-lang/compiler-builtins"
1111
version = "0.2.11"
1212
edition = "2021"
1313
rust-version = "1.63"

0 commit comments

Comments
 (0)