1# `compiler-builtins` 2 3> Porting `compiler-rt` intrinsics to Rust 4 5See [rust-lang/rust#35437][0]. 6 7[0]: https://github.com/rust-lang/rust/issues/35437 8 9## When and how to use this crate? 10 11If you are working with a target that doesn't have binary releases of std 12available via rustup (this probably means you are building the core crate 13yourself) and need compiler-rt intrinsics (i.e. you are probably getting linker 14errors when building an executable: `undefined reference to __aeabi_memcpy`), 15you can use this crate to get those intrinsics and solve the linker errors. To 16do that, add this crate somewhere in the dependency graph of the crate you are 17building: 18 19```toml 20# Cargo.toml 21[dependencies] 22compiler_builtins = { git = "https://github.com/rust-lang/compiler-builtins" } 23``` 24 25```rust 26extern crate compiler_builtins; 27 28// ... 29``` 30 31If you still get an "undefined reference to $INTRINSIC" error after that change, 32that means that we haven't ported `$INTRINSIC` to Rust yet! Please open [an 33issue] with the name of the intrinsic and the LLVM triple (e.g. 34thumbv7m-none-eabi) of the target you are using. That way we can prioritize 35porting that particular intrinsic. 36 37If you've got a C compiler available for your target then while we implement 38this intrinsic you can temporarily enable a fallback to the actual compiler-rt 39implementation as well for unimplemented intrinsics: 40 41```toml 42[dependencies.compiler_builtins] 43git = "https://github.com/rust-lang/compiler-builtins" 44features = ["c"] 45``` 46 47[an issue]: https://github.com/rust-lang/compiler-builtins/issues 48 49## Contributing 50 511. Pick one or more intrinsics from the [pending list](#progress). 522. Fork this repository. 533. Port the intrinsic(s) and their corresponding [unit tests][1] from their 54 [C implementation][2] to Rust. 554. Add a test to compare the behavior of the ported intrinsic(s) with their 56 implementation on the testing host. 575. Add the intrinsic to `examples/intrinsics.rs` to verify it can be linked on 58 all targets. 596. Send a Pull Request (PR). 607. Once the PR passes our extensive testing infrastructure, we'll merge it! 618. Celebrate :tada: 62 63[1]: https://github.com/rust-lang/llvm-project/tree/9e3de9490ff580cd484fbfa2908292b4838d56e7/compiler-rt/test/builtins/Unit 64[2]: https://github.com/rust-lang/llvm-project/tree/9e3de9490ff580cd484fbfa2908292b4838d56e7/compiler-rt/lib/builtins 65[3]: https://github.com/rust-lang/compiler-builtins/actions 66 67### Porting Reminders 68 691. [Rust][5a] and [C][5b] have slightly different operator precedence. C evaluates comparisons (`== !=`) before bitwise operations (`& | ^`), while Rust evaluates the other way. 702. 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. 713. 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. 724. 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. 73 74[5a]: https://doc.rust-lang.org/reference/expressions.html#expression-precedence 75[5b]: http://en.cppreference.com/w/c/language/operator_precedence 76[6]: https://doc.rust-lang.org/core/num/struct.Wrapping.html 77[7]: https://doc.rust-lang.org/std/primitive.i32.html#method.wrapping_add 78[8]: http://en.cppreference.com/w/cpp/language/implicit_conversion 79[9]: https://doc.rust-lang.org/std/primitive.i32.html 80 81## Testing 82 83The easiest way to test locally is using Docker. This can be done by running 84`./ci/run-docker.sh [target]`. If no target is specified, all targets will be 85run. 86 87In order to run the full test suite, you will also need the C compiler runtime 88to test against, located in a directory called `compiler-rt`. This can be 89obtained with the following: 90 91```sh 92curl -L -o rustc-llvm-19.1.tar.gz https://github.com/rust-lang/llvm-project/archive/rustc/19.1-2024-09-17.tar.gz 93tar xzf rustc-llvm-19.1.tar.gz --strip-components 1 llvm-project-rustc-19.1-2024-09-17/compiler-rt 94``` 95 96Local targets may also be tested with `./ci/run.sh [target]`. 97 98Note that testing may not work on all hosts, in which cases it is acceptable to 99rely on CI. 100 101## Progress 102 103- [x] aarch64/chkstk.S 104- [x] adddf3.c 105- [x] addsf3.c 106- [x] arm/addsf3.S 107- [x] arm/aeabi_dcmp.S 108- [x] arm/aeabi_fcmp.S 109- [x] arm/aeabi_idivmod.S 110- [x] arm/aeabi_ldivmod.S 111- [x] arm/aeabi_memcpy.S 112- [x] arm/aeabi_memmove.S 113- [x] arm/aeabi_memset.S 114- [x] arm/aeabi_uidivmod.S 115- [x] arm/aeabi_uldivmod.S 116- [ ] arm/chkstk.S 117- [ ] arm/divmodsi4.S (generic version is done) 118- [ ] arm/divsi3.S (generic version is done) 119- [ ] arm/modsi3.S (generic version is done) 120- [x] arm/softfloat-alias.list 121- [ ] arm/udivmodsi4.S (generic version is done) 122- [ ] arm/udivsi3.S (generic version is done) 123- [ ] arm/umodsi3.S (generic version is done) 124- [x] ashldi3.c 125- [x] ashrdi3.c 126- [ ] avr/divmodhi4.S 127- [ ] avr/divmodqi4.S 128- [ ] avr/mulhi3.S 129- [ ] avr/mulqi3.S 130- [ ] avr/udivmodhi4.S 131- [ ] avr/udivmodqi4.S 132- [x] bswapdi2.c 133- [x] bswapsi2.c 134- [x] bswapti2.c 135- [x] clzdi2.c 136- [x] clzsi2.c 137- [x] clzti2.c 138- [x] comparedf2.c 139- [x] comparesf2.c 140- [x] ctzdi2.c 141- [x] ctzsi2.c 142- [x] ctzti2.c 143- [x] divdf3.c 144- [x] divdi3.c 145- [x] divmoddi4.c 146- [x] divmodsi4.c 147- [x] divmodti4.c 148- [x] divsf3.c 149- [x] divsi3.c 150- [x] extendsfdf2.c 151- [x] fixdfdi.c 152- [x] fixdfsi.c 153- [x] fixsfdi.c 154- [x] fixsfsi.c 155- [x] fixunsdfdi.c 156- [x] fixunsdfsi.c 157- [x] fixunssfdi.c 158- [x] fixunssfsi.c 159- [x] floatdidf.c 160- [x] floatdisf.c 161- [x] floatsidf.c 162- [x] floatsisf.c 163- [x] floatundidf.c 164- [x] floatundisf.c 165- [x] floatunsidf.c 166- [x] floatunsisf.c 167- [ ] i386/ashldi3.S 168- [ ] i386/ashrdi3.S 169- [x] i386/chkstk.S 170- [ ] i386/divdi3.S 171- [ ] i386/lshrdi3.S 172- [ ] i386/moddi3.S 173- [ ] i386/muldi3.S 174- [ ] i386/udivdi3.S 175- [ ] i386/umoddi3.S 176- [x] lshrdi3.c 177- [x] moddi3.c 178- [x] modsi3.c 179- [x] muldf3.c 180- [x] muldi3.c 181- [x] mulodi4.c 182- [x] mulosi4.c 183- [x] mulsf3.c 184- [x] powidf2.c 185- [x] powisf2.c 186- [ ] riscv/muldi3.S 187- [ ] riscv/mulsi3.S 188- [x] subdf3.c 189- [x] subsf3.c 190- [x] truncdfsf2.c 191- [x] udivdi3.c 192- [x] udivmoddi4.c 193- [x] udivmodsi4.c 194- [x] udivsi3.c 195- [x] umoddi3.c 196- [x] umodsi3.c 197- [x] x86_64/chkstk.S 198 199These builtins are needed to support 128-bit integers. 200 201- [x] ashlti3.c 202- [x] ashrti3.c 203- [x] divti3.c 204- [x] fixdfti.c 205- [x] fixsfti.c 206- [x] fixunsdfti.c 207- [x] fixunssfti.c 208- [x] floattidf.c 209- [x] floattisf.c 210- [x] floatuntidf.c 211- [x] floatuntisf.c 212- [x] lshrti3.c 213- [x] modti3.c 214- [x] muloti4.c 215- [x] multi3.c 216- [x] udivmodti4.c 217- [x] udivti3.c 218- [x] umodti3.c 219 220These builtins are needed to support `f16` and `f128`, which are in the process 221of being added to Rust. 222 223- [x] addtf3.c 224- [x] comparetf2.c 225- [x] divtf3.c 226- [x] extenddftf2.c 227- [x] extendhfsf2.c 228- [x] extendhftf2.c 229- [x] extendsftf2.c 230- [x] fixtfdi.c 231- [x] fixtfsi.c 232- [x] fixtfti.c 233- [x] fixunstfdi.c 234- [x] fixunstfsi.c 235- [x] fixunstfti.c 236- [ ] floatditf.c 237- [ ] floatsitf.c 238- [ ] floattitf.c 239- [ ] floatunditf.c 240- [ ] floatunsitf.c 241- [ ] floatuntitf.c 242- [x] multf3.c 243- [x] powitf2.c 244- [x] subtf3.c 245- [x] truncdfhf2.c 246- [x] truncsfhf2.c 247- [x] trunctfdf2.c 248- [x] trunctfhf2.c 249- [x] trunctfsf2.c 250 251 252These builtins are used by the Hexagon DSP 253 254- [ ] hexagon/common_entry_exit_abi1.S 255- [ ] hexagon/common_entry_exit_abi2.S 256- [ ] hexagon/common_entry_exit_legacy.S 257- [x] hexagon/dfaddsub.S~~ 258- [x] hexagon/dfdiv.S~~ 259- [x] hexagon/dffma.S~~ 260- [x] hexagon/dfminmax.S~~ 261- [x] hexagon/dfmul.S~~ 262- [x] hexagon/dfsqrt.S~~ 263- [x] hexagon/divdi3.S~~ 264- [x] hexagon/divsi3.S~~ 265- [x] hexagon/fastmath2_dlib_asm.S~~ 266- [x] hexagon/fastmath2_ldlib_asm.S~~ 267- [x] hexagon/fastmath_dlib_asm.S~~ 268- [x] hexagon/memcpy_forward_vp4cp4n2.S~~ 269- [x] hexagon/memcpy_likely_aligned.S~~ 270- [x] hexagon/moddi3.S~~ 271- [x] hexagon/modsi3.S~~ 272- [x] hexagon/sfdiv_opt.S~~ 273- [x] hexagon/sfsqrt_opt.S~~ 274- [x] hexagon/udivdi3.S~~ 275- [x] hexagon/udivmoddi4.S~~ 276- [x] hexagon/udivmodsi4.S~~ 277- [x] hexagon/udivsi3.S~~ 278- [x] hexagon/umoddi3.S~~ 279- [x] hexagon/umodsi3.S~~ 280 281## Unimplemented functions 282 283These builtins are for x87 `f80` floating-point numbers that are not supported 284by Rust. 285 286- ~~extendxftf2.c~~ 287- ~~fixunsxfdi.c~~ 288- ~~fixunsxfsi.c~~ 289- ~~fixunsxfti.c~~ 290- ~~fixxfdi.c~~ 291- ~~fixxfti.c~~ 292- ~~floatdixf.c~~ 293- ~~floattixf.c~~ 294- ~~floatundixf.c~~ 295- ~~floatuntixf.c~~ 296- ~~i386/floatdixf.S~~ 297- ~~i386/floatundixf.S~~ 298- ~~x86_64/floatdixf.c~~ 299- ~~x86_64/floatundixf.S~~ 300 301These builtins are for IBM "extended double" non-IEEE 128-bit floating-point 302numbers. 303 304- ~~ppc/divtc3.c~~ 305- ~~ppc/fixtfdi.c~~ 306- ~~ppc/fixtfti.c~~ 307- ~~ppc/fixunstfdi.c~~ 308- ~~ppc/fixunstfti.c~~ 309- ~~ppc/floatditf.c~~ 310- ~~ppc/floattitf.c~~ 311- ~~ppc/floatunditf.c~~ 312- ~~ppc/gcc_qadd.c~~ 313- ~~ppc/gcc_qdiv.c~~ 314- ~~ppc/gcc_qmul.c~~ 315- ~~ppc/gcc_qsub.c~~ 316- ~~ppc/multc3.c~~ 317 318These builtins are for 16-bit brain floating-point numbers that are not 319supported by Rust. 320 321- ~~truncdfbf2.c~~ 322- ~~truncsfbf2.c~~ 323- ~~trunctfxf2.c~~ 324 325These builtins involve complex floating-point types that are not supported by 326Rust. 327 328- ~~divdc3.c~~ 329- ~~divsc3.c~~ 330- ~~divtc3.c~~ 331- ~~divxc3.c~~ 332- ~~muldc3.c~~ 333- ~~mulsc3.c~~ 334- ~~multc3.c~~ 335- ~~mulxc3.c~~ 336- ~~powixf2.c~~ 337 338These builtins are never called by LLVM. 339 340- ~~absvdi2.c~~ 341- ~~absvsi2.c~~ 342- ~~absvti2.c~~ 343- ~~addvdi3.c~~ 344- ~~addvsi3.c~~ 345- ~~addvti3.c~~ 346- ~~arm/aeabi_cdcmp.S~~ 347- ~~arm/aeabi_cdcmpeq_check_nan.c~~ 348- ~~arm/aeabi_cfcmp.S~~ 349- ~~arm/aeabi_cfcmpeq_check_nan.c~~ 350- ~~arm/aeabi_div0.c~~ 351- ~~arm/aeabi_drsub.c~~ 352- ~~arm/aeabi_frsub.c~~ 353- ~~arm/aeabi_memcmp.S~~ 354- ~~arm/bswapdi2.S~~ 355- ~~arm/bswapsi2.S~~ 356- ~~arm/clzdi2.S~~ 357- ~~arm/clzsi2.S~~ 358- ~~arm/comparesf2.S~~ 359- ~~arm/restore_vfp_d8_d15_regs.S~~ 360- ~~arm/save_vfp_d8_d15_regs.S~~ 361- ~~arm/switch16.S~~ 362- ~~arm/switch32.S~~ 363- ~~arm/switch8.S~~ 364- ~~arm/switchu8.S~~ 365- ~~cmpdi2.c~~ 366- ~~cmpti2.c~~ 367- ~~ffssi2.c~~ 368- ~~ffsdi2.c~~ - this is [called by gcc][jemalloc-fail] though! 369- ~~ffsti2.c~~ 370- ~~mulvdi3.c~~ 371- ~~mulvsi3.c~~ 372- ~~mulvti3.c~~ 373- ~~negdf2.c~~ 374- ~~negdi2.c~~ 375- ~~negsf2.c~~ 376- ~~negti2.c~~ 377- ~~negvdi2.c~~ 378- ~~negvsi2.c~~ 379- ~~negvti2.c~~ 380- ~~paritydi2.c~~ 381- ~~paritysi2.c~~ 382- ~~parityti2.c~~ 383- ~~popcountdi2.c~~ 384- ~~popcountsi2.c~~ 385- ~~popcountti2.c~~ 386- ~~ppc/restFP.S~~ 387- ~~ppc/saveFP.S~~ 388- ~~subvdi3.c~~ 389- ~~subvsi3.c~~ 390- ~~subvti3.c~~ 391- ~~ucmpdi2.c~~ 392- ~~ucmpti2.c~~ 393- ~~udivmodti4.c~~ 394 395[jemalloc-fail]: https://travis-ci.org/rust-lang/rust/jobs/249772758 396 397Rust only exposes atomic types on platforms that support them, and therefore does not need to fall back to software implementations. 398 399- ~~arm/sync_fetch_and_add_4.S~~ 400- ~~arm/sync_fetch_and_add_8.S~~ 401- ~~arm/sync_fetch_and_and_4.S~~ 402- ~~arm/sync_fetch_and_and_8.S~~ 403- ~~arm/sync_fetch_and_max_4.S~~ 404- ~~arm/sync_fetch_and_max_8.S~~ 405- ~~arm/sync_fetch_and_min_4.S~~ 406- ~~arm/sync_fetch_and_min_8.S~~ 407- ~~arm/sync_fetch_and_nand_4.S~~ 408- ~~arm/sync_fetch_and_nand_8.S~~ 409- ~~arm/sync_fetch_and_or_4.S~~ 410- ~~arm/sync_fetch_and_or_8.S~~ 411- ~~arm/sync_fetch_and_sub_4.S~~ 412- ~~arm/sync_fetch_and_sub_8.S~~ 413- ~~arm/sync_fetch_and_umax_4.S~~ 414- ~~arm/sync_fetch_and_umax_8.S~~ 415- ~~arm/sync_fetch_and_umin_4.S~~ 416- ~~arm/sync_fetch_and_umin_8.S~~ 417- ~~arm/sync_fetch_and_xor_4.S~~ 418- ~~arm/sync_fetch_and_xor_8.S~~ 419- ~~arm/sync_synchronize.S~~ 420- ~~atomic.c~~ 421- ~~atomic_flag_clear.c~~ 422- ~~atomic_flag_clear_explicit.c~~ 423- ~~atomic_flag_test_and_set.c~~ 424- ~~atomic_flag_test_and_set_explicit.c~~ 425- ~~atomic_signal_fence.c~~ 426- ~~atomic_thread_fence.c~~ 427 428Miscellaneous functionality that is not used by Rust. 429 430- ~~aarch64/fp_mode.c~~ 431- ~~aarch64/lse.S~~ (LSE atomics) 432- ~~aarch64/sme-abi-init.c~~ (matrix extension) 433- ~~aarch64/sme-abi.S~~ (matrix extension) 434- ~~aarch64/sme-libc-routines.c~~ (matrix extension) 435- ~~apple_versioning.c~~ 436- ~~arm/fp_mode.c~~ 437- ~~avr/exit.S~~ 438- ~~clear_cache.c~~ 439- ~~cpu_model/aarch64.c~~ 440- ~~cpu_model/x86.c~~ 441- ~~crtbegin.c~~ 442- ~~crtend.c~~ 443- ~~emutls.c~~ 444- ~~enable_execute_stack.c~~ 445- ~~eprintf.c~~ 446- ~~fp_mode.c~~ (float exception handling) 447- ~~gcc_personality_v0.c~~ 448- ~~i386/fp_mode.c~~ 449- ~~int_util.c~~ 450- ~~loongarch/fp_mode.c~~ 451- ~~os_version_check.c~~ 452- ~~riscv/fp_mode.c~~ 453- ~~riscv/restore.S~~ (callee-saved registers) 454- ~~riscv/save.S~~ (callee-saved registers) 455- ~~trampoline_setup.c~~ 456- ~~ve/grow_stack.S~~ 457- ~~ve/grow_stack_align.S~~ 458 459Floating-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. 460 461- ~~i386/floatdidf.S~~ 462- ~~i386/floatdisf.S~~ 463- ~~i386/floatundidf.S~~ 464- ~~i386/floatundisf.S~~ 465- ~~x86_64/floatundidf.S~~ 466- ~~x86_64/floatundisf.S~~ 467- ~~x86_64/floatdidf.c~~ 468- ~~x86_64/floatdisf.c~~ 469 470Unsupported in any current target: used on old versions of 32-bit iOS with ARMv5. 471 472- ~~arm/adddf3vfp.S~~ 473- ~~arm/addsf3vfp.S~~ 474- ~~arm/divdf3vfp.S~~ 475- ~~arm/divsf3vfp.S~~ 476- ~~arm/eqdf2vfp.S~~ 477- ~~arm/eqsf2vfp.S~~ 478- ~~arm/extendsfdf2vfp.S~~ 479- ~~arm/fixdfsivfp.S~~ 480- ~~arm/fixsfsivfp.S~~ 481- ~~arm/fixunsdfsivfp.S~~ 482- ~~arm/fixunssfsivfp.S~~ 483- ~~arm/floatsidfvfp.S~~ 484- ~~arm/floatsisfvfp.S~~ 485- ~~arm/floatunssidfvfp.S~~ 486- ~~arm/floatunssisfvfp.S~~ 487- ~~arm/gedf2vfp.S~~ 488- ~~arm/gesf2vfp.S~~ 489- ~~arm/gtdf2vfp.S~~ 490- ~~arm/gtsf2vfp.S~~ 491- ~~arm/ledf2vfp.S~~ 492- ~~arm/lesf2vfp.S~~ 493- ~~arm/ltdf2vfp.S~~ 494- ~~arm/ltsf2vfp.S~~ 495- ~~arm/muldf3vfp.S~~ 496- ~~arm/mulsf3vfp.S~~ 497- ~~arm/nedf2vfp.S~~ 498- ~~arm/negdf2vfp.S~~ 499- ~~arm/negsf2vfp.S~~ 500- ~~arm/nesf2vfp.S~~ 501- ~~arm/subdf3vfp.S~~ 502- ~~arm/subsf3vfp.S~~ 503- ~~arm/truncdfsf2vfp.S~~ 504- ~~arm/unorddf2vfp.S~~ 505- ~~arm/unordsf2vfp.S~~ 506 507## License 508 509The compiler-builtins crate is dual licensed under both the University of 510Illinois "BSD-Like" license and the MIT license. As a user of this code you may 511choose to use it under either license. As a contributor, you agree to allow 512your code to be used under both. 513 514Full text of the relevant licenses is in LICENSE.TXT. 515