2016-08-24 09:23:28 +08:00
[![Travis][travis]](https://travis-ci.org/japaric/rustc-builtins)
[![AppVeyor][appveyor]](https://ci.appveyor.com/project/japaric/rustc-builtins)
2016-08-08 04:58:05 +08:00
2016-08-24 09:23:28 +08:00
[appveyor]: https://ci.appveyor.com/api/projects/status/mofi55r3px9pv3o7?svg=true
2016-09-11 07:37:35 +08:00
[travis]: https://travis-ci.org/japaric/rustc-builtins.svg?branch=master
2016-08-08 04:58:05 +08:00
# `rustc-builtins`
> [WIP] Porting `compiler-rt` intrinsics to Rust
2016-08-08 05:01:28 +08:00
See [rust-lang/rust#35437][0].
[0]: https://github.com/rust-lang/rust/issues/35437
2016-08-24 09:35:30 +08:00
## When and how to use this crate?
If you are working with a target that doesn't have binary releases of std available via rustup (this
probably means you are building the core crate yourself) and need compiler-rt intrinsics (i.e. you
are probably getting linker errors when building an executable: "undefined reference to
__aeabi_memcpy"), you can use this crate to get those intrinsics and solve the linker errors. To do
that, simply add this crate as a Cargo dependency (it doesn't matter where in the dependency graph
this crate ends up, as long as it's there):
``` toml
[dependencies]
rustc-builtins = { git = "https://github.com/japaric/rustc-builtins" }
```
If you still get an "undefined reference to $INTRINSIC" error after that change, that means that we
haven't ported `$INTRINSIC` to Rust yet! Please open [an issue] with the name of the intrinsic and
the LLVM triple (e.g. thumbv7m-none-eabi) of the target you are using. That way we can prioritize
porting that particular intrinsic.
[an issue]: https://github.com/japaric/rustc-builtins/issues
2016-08-08 10:05:42 +08:00
## Contributing
2016-08-24 09:17:39 +08:00
1. Pick one or more intrinsics from the [pending list][#progress].
2016-08-08 10:05:42 +08:00
2. Fork this repository
3. Port the intrinsic(s) and their corresponding [unit tests][1] from their [C implementation][2] to
Rust.
4. Send a Pull Request (PR)
5. Once the PR passes our extensive [testing infrastructure][3], we'll merge it!
6. Celebrate :tada:
[1]: https://github.com/rust-lang/compiler-rt/tree/8598065bd965d9713bfafb6c1e766d63a7b17b89/test/builtins/Unit
[2]: https://github.com/rust-lang/compiler-rt/tree/8598065bd965d9713bfafb6c1e766d63a7b17b89/lib/builtins
[3]: https://travis-ci.org/japaric/rustc-builtins
2016-08-22 02:31:08 +08:00
### Porting Reminders
1. [Rust][4] and [C][5] have slightly different operator precedence. C evaluates comparisons (`== !=`) before bitwise operations (`& | ^`), while Rust evaluates the other way.
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.
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.
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.
[4]: https://doc.rust-lang.org/reference.html#operator-precedence
[5]: http://en.cppreference.com/w/c/language/operator_precedence
[6]: https://doc.rust-lang.org/core/num/struct.Wrapping.html
[7]: https://doc.rust-lang.org/std/primitive.i32.html#method.wrapping_add
[8]: http://en.cppreference.com/w/cpp/language/implicit_conversion
[9]: https://doc.rust-lang.org/std/primitive.i32.html
2016-08-08 10:05:42 +08:00
## Progress
2016-08-18 04:51:37 +08:00
- [x] adddf3.c
- [x] addsf3.c
2016-08-08 10:05:42 +08:00
- [ ] arm/adddf3vfp.S
- [ ] arm/addsf3vfp.S
- [ ] arm/aeabi_dcmp.S
- [ ] arm/aeabi_fcmp.S
2016-08-11 15:12:01 +08:00
- [x] arm/aeabi_idivmod.S
- [x] arm/aeabi_ldivmod.S
2016-08-08 15:27:22 +08:00
- [x] arm/aeabi_memcpy.S
- [x] arm/aeabi_memmove.S
- [x] arm/aeabi_memset.S
2016-08-13 16:51:54 +08:00
- [x] arm/aeabi_uidivmod.S
- [x] arm/aeabi_uldivmod.S
2016-08-08 10:05:42 +08:00
- [ ] arm/divdf3vfp.S
2016-08-19 00:20:24 +08:00
- [ ] arm/divmodsi4.S (generic version is done)
2016-08-08 10:05:42 +08:00
- [ ] arm/divsf3vfp.S
2016-08-19 00:20:24 +08:00
- [ ] arm/divsi3.S (generic version is done)
2016-08-08 10:05:42 +08:00
- [ ] arm/eqdf2vfp.S
- [ ] arm/eqsf2vfp.S
- [ ] arm/extendsfdf2vfp.S
- [ ] arm/fixdfsivfp.S
- [ ] arm/fixsfsivfp.S
- [ ] arm/fixunsdfsivfp.S
- [ ] arm/fixunssfsivfp.S
- [ ] arm/floatsidfvfp.S
- [ ] arm/floatsisfvfp.S
- [ ] arm/floatunssidfvfp.S
- [ ] arm/floatunssisfvfp.S
- [ ] arm/gedf2vfp.S
- [ ] arm/gesf2vfp.S
- [ ] arm/gtdf2vfp.S
- [ ] arm/gtsf2vfp.S
- [ ] arm/ledf2vfp.S
- [ ] arm/lesf2vfp.S
- [ ] arm/ltdf2vfp.S
- [ ] arm/ltsf2vfp.S
2016-08-19 00:20:24 +08:00
- [ ] arm/modsi3.S (generic version is done)
2016-08-08 10:05:42 +08:00
- [ ] arm/muldf3vfp.S
- [ ] arm/mulsf3vfp.S
- [ ] arm/nedf2vfp.S
- [ ] arm/negdf2vfp.S
- [ ] arm/negsf2vfp.S
- [ ] arm/nesf2vfp.S
- [ ] arm/softfloat-alias.list
- [ ] arm/subdf3vfp.S
- [ ] arm/subsf3vfp.S
- [ ] arm/truncdfsf2vfp.S
2016-08-19 00:20:24 +08:00
- [ ] arm/udivmodsi4.S (generic version is done)
- [ ] arm/udivsi3.S (generic version is done)
- [ ] arm/umodsi3.S (generic version is done)
2016-08-08 10:05:42 +08:00
- [ ] arm/unorddf2vfp.S
- [ ] arm/unordsf2vfp.S
2016-08-13 16:51:54 +08:00
- [x] ashldi3.c
- [x] ashrdi3.c
2016-08-08 10:05:42 +08:00
- [ ] divdf3.c
2016-08-19 00:20:24 +08:00
- [x] divdi3.c
- [x] divmoddi4.c
- [x] divmodsi4.c
2016-08-08 10:05:42 +08:00
- [ ] divsf3.c
2016-08-19 00:20:24 +08:00
- [x] divsi3.c
2016-08-08 10:05:42 +08:00
- [ ] extendhfsf2.c
- [ ] extendsfdf2.c
- [ ] fixdfdi.c
- [ ] fixdfsi.c
- [ ] fixsfdi.c
- [ ] fixsfsi.c
- [ ] fixunsdfdi.c
- [ ] fixunsdfsi.c
- [ ] fixunssfdi.c
- [ ] fixunssfsi.c
- [ ] floatdidf.c
- [ ] floatdisf.c
- [ ] floatsidf.c
- [ ] floatsisf.c
- [ ] floatundidf.c
- [ ] floatundisf.c
- [ ] floatunsidf.c
- [ ] floatunsisf.c
- [ ] i386/ashldi3.S
- [ ] i386/ashrdi3.S
- [ ] i386/chkstk.S
- [ ] i386/chkstk2.S
- [ ] i386/divdi3.S
- [ ] i386/lshrdi3.S
- [ ] i386/moddi3.S
- [ ] i386/muldi3.S
- [ ] i386/udivdi3.S
- [ ] i386/umoddi3.S
2016-08-13 16:51:54 +08:00
- [x] lshrdi3.c
2016-08-19 00:20:24 +08:00
- [x] moddi3.c
- [x] modsi3.c
2016-08-08 10:05:42 +08:00
- [ ] muldf3.c
2016-08-13 16:51:54 +08:00
- [x] muldi3.c
- [x] mulodi4.c
- [x] mulosi4.c
2016-08-08 10:05:42 +08:00
- [ ] mulsf3.c
- [ ] powidf2.c
- [ ] powisf2.c
- [ ] subdf3.c
- [ ] subsf3.c
- [ ] truncdfhf2.c
- [ ] truncdfsf2.c
- [ ] truncsfhf2.c
2016-08-13 16:51:54 +08:00
- [x] udivdi3.c
2016-08-11 15:12:01 +08:00
- [x] udivmoddi4.c
- [x] udivmodsi4.c
2016-08-13 16:51:54 +08:00
- [x] udivsi3.c
- [x] umoddi3.c
- [x] umodsi3.c
2016-08-18 03:35:48 +08:00
- [x] x86_64/chkstk.S
- [x] x86_64/chkstk2.S
2016-08-08 13:54:00 +08:00
2016-08-13 16:51:54 +08:00
These builtins are needed to support 128-bit integers, which are in the process of being added to Rust.
- [ ] ashlti3.c
- [ ] ashrti3.c
- [ ] divti3.c
- [ ] fixdfti.c
- [ ] fixsfti.c
- [ ] fixunsdfti.c
- [ ] fixunssfti.c
- [ ] floattidf.c
- [ ] floattisf.c
- [ ] floatuntidf.c
- [ ] floatuntisf.c
- [ ] lshrti3.c
- [ ] modti3.c
- [ ] muloti4.c
- [ ] multi3.c
- [ ] udivmodti4.c
- [ ] udivti3.c
- [ ] umodti3.c
2016-08-08 13:54:00 +08:00
## Unimplemented functions
These builtins involve floating-point types ("`f128`", "`f80`" and complex numbers) that are not supported by Rust.
- ~~addtf3.c~~
- ~~comparetf2.c~~
- ~~divdc3.c~~
- ~~divsc3.c~~
- ~~divtc3.c~~
- ~~divtf3.c~~
- ~~divxc3.c~~
- ~~extenddftf2.c~~
- ~~extendsftf2.c~~
- ~~fixtfdi.c~~
- ~~fixtfsi.c~~
- ~~fixtfti.c~~
- ~~fixunstfdi.c~~
- ~~fixunstfsi.c~~
- ~~fixunstfti.c~~
2016-08-08 10:05:42 +08:00
- ~~fixunsxfdi.c~~
- ~~fixunsxfsi.c~~
- ~~fixunsxfti.c~~
- ~~fixxfdi.c~~
- ~~fixxfti.c~~
2016-08-08 13:54:00 +08:00
- ~~floatditf.c~~
2016-08-08 10:05:42 +08:00
- ~~floatdixf.c~~
2016-08-08 13:54:00 +08:00
- ~~floatsitf.c~~
2016-08-08 10:05:42 +08:00
- ~~floattixf.c~~
2016-08-08 13:54:00 +08:00
- ~~floatunditf.c~~
2016-08-08 10:05:42 +08:00
- ~~floatundixf.c~~
2016-08-08 13:54:00 +08:00
- ~~floatunsitf.c~~
2016-08-08 10:05:42 +08:00
- ~~floatuntixf.c~~
- ~~i386/floatdixf.S~~
- ~~i386/floatundixf.S~~
2016-08-08 13:54:00 +08:00
- ~~muldc3.c~~
- ~~mulsc3.c~~
- ~~multc3.c~~
- ~~multf3.c~~
- ~~mulxc3.c~~
- ~~powitf2.c~~
2016-08-08 10:05:42 +08:00
- ~~powixf2.c~~
2016-08-08 13:54:00 +08:00
- ~~ppc/divtc3.c~~
- ~~ppc/fixtfdi.c~~
- ~~ppc/fixunstfdi.c~~
- ~~ppc/floatditf.c~~
- ~~ppc/floatunditf.c~~
2016-08-08 15:16:54 +08:00
- ~~ppc/gcc_qadd.c~~
- ~~ppc/gcc_qdiv.c~~
- ~~ppc/gcc_qmul.c~~
- ~~ppc/gcc_qsub.c~~
2016-08-08 13:54:00 +08:00
- ~~ppc/multc3.c~~
- ~~subtf3.c~~
- ~~trunctfdf2.c~~
- ~~trunctfsf2.c~~
2016-08-08 10:05:42 +08:00
- ~~x86_64/floatdixf.c~~
- ~~x86_64/floatundixf.S~~
2016-08-08 15:16:54 +08:00
These builtins are never called by LLVM.
- ~~absvdi2.c~~
- ~~absvsi2.c~~
- ~~absvti2.c~~
- ~~addvdi3.c~~
- ~~addvsi3.c~~
- ~~addvti3.c~~
- ~~arm/aeabi_cdcmp.S~~
- ~~arm/aeabi_cdcmpeq_check_nan.c~~
- ~~arm/aeabi_cfcmp.S~~
- ~~arm/aeabi_cfcmpeq_check_nan.c~~
- ~~arm/aeabi_div0.c~~
- ~~arm/aeabi_drsub.c~~
- ~~arm/aeabi_frsub.c~~
- ~~arm/aeabi_memcmp.S~~
- ~~arm/bswapdi2.S~~
- ~~arm/bswapsi2.S~~
- ~~arm/clzdi2.S~~
- ~~arm/clzsi2.S~~
- ~~arm/comparesf2.S~~
- ~~arm/restore_vfp_d8_d15_regs.S~~
- ~~arm/save_vfp_d8_d15_regs.S~~
- ~~arm/switch16.S~~
- ~~arm/switch32.S~~
- ~~arm/switch8.S~~
- ~~arm/switchu8.S~~
- ~~clzdi2.c~~
- ~~clzsi2.c~~
- ~~clzti2.c~~
- ~~cmpdi2.c~~
- ~~cmpti2.c~~
- ~~comparedf2.c~~
- ~~comparesf2.c~~
- ~~ctzdi2.c~~
- ~~ctzsi2.c~~
- ~~ctzti2.c~~
- ~~ffsdi2.c~~
- ~~ffsti2.c~~
- ~~mulvdi3.c~~
- ~~mulvsi3.c~~
- ~~mulvti3.c~~
- ~~negdf2.c~~
- ~~negdi2.c~~
- ~~negsf2.c~~
- ~~negti2.c~~
- ~~negvdi2.c~~
- ~~negvsi2.c~~
- ~~negvti2.c~~
- ~~paritydi2.c~~
- ~~paritysi2.c~~
- ~~parityti2.c~~
- ~~popcountdi2.c~~
- ~~popcountsi2.c~~
- ~~popcountti2.c~~
- ~~ppc/restFP.S~~
- ~~ppc/saveFP.S~~
- ~~subvdi3.c~~
- ~~subvsi3.c~~
- ~~subvti3.c~~
- ~~ucmpdi2.c~~
- ~~ucmpti2.c~~
- ~~udivmodti4.c~~
2016-08-08 13:54:00 +08:00
Rust only exposes atomic types on platforms that support them, and therefore does not need to fall back to software implementations.
- ~~arm/sync_fetch_and_add_4.S~~
- ~~arm/sync_fetch_and_add_8.S~~
- ~~arm/sync_fetch_and_and_4.S~~
- ~~arm/sync_fetch_and_and_8.S~~
- ~~arm/sync_fetch_and_max_4.S~~
- ~~arm/sync_fetch_and_max_8.S~~
- ~~arm/sync_fetch_and_min_4.S~~
- ~~arm/sync_fetch_and_min_8.S~~
- ~~arm/sync_fetch_and_nand_4.S~~
- ~~arm/sync_fetch_and_nand_8.S~~
- ~~arm/sync_fetch_and_or_4.S~~
- ~~arm/sync_fetch_and_or_8.S~~
- ~~arm/sync_fetch_and_sub_4.S~~
- ~~arm/sync_fetch_and_sub_8.S~~
- ~~arm/sync_fetch_and_umax_4.S~~
- ~~arm/sync_fetch_and_umax_8.S~~
- ~~arm/sync_fetch_and_umin_4.S~~
- ~~arm/sync_fetch_and_umin_8.S~~
- ~~arm/sync_fetch_and_xor_4.S~~
- ~~arm/sync_fetch_and_xor_8.S~~
- ~~arm/sync_synchronize.S~~
- ~~atomic.c~~
- ~~atomic_flag_clear.c~~
- ~~atomic_flag_clear_explicit.c~~
- ~~atomic_flag_test_and_set.c~~
- ~~atomic_flag_test_and_set_explicit.c~~
- ~~atomic_signal_fence.c~~
- ~~atomic_thread_fence.c~~
Miscellaneous functionality that is not used by Rust.
- ~~apple_versioning.c~~
- ~~clear_cache.c~~
- ~~emutls.c~~
- ~~enable_execute_stack.c~~
- ~~eprintf.c~~
- ~~gcc_personality_v0.c~~
- ~~trampoline_setup.c~~
2016-08-08 15:27:22 +08:00
Floating-point implementations of builtins that are only called from soft-float code. It would be better to simply use the generic soft-float versions in this case.
- ~~i386/floatdidf.S~~
- ~~i386/floatdisf.S~~
- ~~i386/floatundidf.S~~
- ~~i386/floatundisf.S~~
- ~~x86_64/floatundidf.S~~
- ~~x86_64/floatundisf.S~~
- ~~x86_64/floatdidf.c~~
- ~~x86_64/floatdisf.c~~
2016-08-08 04:58:05 +08:00
## License
Licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the
work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.