112次发布
新 0.1.121 | 2024年8月22日 |
---|---|
0.1.114 | 2024年7月28日 |
0.1.108 | 2024年2月5日 |
0.1.105 | 2023年12月14日 |
0.1.2 | 2018年11月26日 |
39 in Rust模式
560,778 monthly downloads
用于 70 个crate(66 个直接)
1MB
18K SLoC
compiler-builtins
将
compiler-rt
内建函数移植到Rust
何时以及如何使用此crate?
如果您正在使用一个没有通过rustup提供二进制发布版的std的目标(这可能意味着您正在自己构建核心crate)并且需要编译器-rt内建函数(即您在构建可执行文件时可能遇到链接器错误:undefined reference to __aeabi_memcpy
),您可以使用此crate来获取这些内建函数并解决链接器错误。为此,将此crate添加到您正在构建的crate的依赖关系图中
# Cargo.toml
[dependencies]
compiler_builtins = { git = "https://github.com/rust-lang/compiler-builtins" }
extern crate compiler_builtins;
// ...
如果您在更改后仍然收到“未定义引用到$INTRINSIC”的错误,这意味着我们还没有将$INTRINSIC
移植到Rust。请打开一个issue,并提供内建函数名称和您使用的目标的LLVM triple(例如,thumbv7m-none-eabi)。这样我们就可以优先移植该特定的内建函数。
如果您的目标有可用的C编译器,那么在我们实现这个内建函数的同时,您可以暂时为未实现的内建函数启用对实际compiler-rt实现的回退。
[dependencies.compiler_builtins]
git = "https://github.com/rust-lang/compiler-builtins"
features = ["c"]
贡献
- 从待办列表中选择一个或多个内建函数。
- 此仓库。
- 将内建函数及其对应的单元测试从它们的C实现移植到Rust。
- 添加一个测试,以比较移植的内建函数与测试主机上的实现的行为。
- 将内建函数添加到
examples/intrinsics.rs
,以验证它可以在所有目标上链接。 - 发送一个Pull Request (PR)。
- 一旦PR通过了我们的全面测试基础设施,我们就会合并它!
- 庆祝 🎉
移植提示
- Rust 和 C 的运算符优先级略有不同。C先计算比较操作(
== !=
),然后是位操作(& | ^
),而Rust则相反。 - C假设所有操作都会进行包装。在调试模式下,Rust在溢出时会产生恐慌。考虑使用Wrapping类型或相应的显式wrapping_*函数。
- 注意C隐式转换,特别是整数提升。Rust在类型转换方面更加明确,所以请确保任何影响输出的转换都移植到了Rust实现中。
- Rust标准库中有许多用于整数或浮点数操作的函数。考虑使用这些函数之一,而不是移植一个新的函数。
测试
在本地测试的最简单方法是使用Docker。可以通过运行./ci/run-docker.sh [target]
来完成。如果没有指定目标,将运行所有目标。
为了运行完整的测试套件,您还需要C编译器运行时,位于名为compiler-rt
的目录中。可以使用以下方式获取:
curl -L -o rustc-llvm-18.0.tar.gz https://github.com/rust-lang/llvm-project/archive/rustc/18.0-2024-02-13.tar.gz
tar xzf rustc-llvm-18.0.tar.gz --strip-components 1 llvm-project-rustc-18.0-2024-02-13/compiler-rt
还可以使用./ci/run.sh [target]
在本地目标上测试。
请注意,测试可能不在所有主机上工作,在这种情况下,可以依赖于CI。
进度
- aarch64/chkstk.S
- adddf3.c
- addsf3.c
- arm/adddf3vfp.S
- arm/addsf3.S
- arm/addsf3vfp.S
- arm/aeabi_dcmp.S
- arm/aeabi_fcmp.S
- arm/aeabi_idivmod.S
- arm/aeabi_ldivmod.S
- arm/aeabi_memcpy.S
- arm/aeabi_memmove.S
- arm/aeabi_memset.S
- arm/aeabi_uidivmod.S
- arm/aeabi_uldivmod.S
- arm/chkstk.S
- arm/divdf3vfp.S
- arm/divmodsi4.S (通用版本已完成)
- arm/divsf3vfp.S
- arm/divsi3.S (通用版本已完成)
- 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
- arm/modsi3.S (通用版本已完成)
- 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
- arm/udivmodsi4.S (通用版本已完成)
- arm/udivsi3.S (通用版本已完成)
- arm/umodsi3.S (通用版本已完成)
- arm/unorddf2vfp.S
- arm/unordsf2vfp.S
- ashldi3.c
- ashrdi3.c
- avr/divmodhi4.S
- avr/divmodqi4.S
- avr/mulhi3.S
- avr/mulqi3.S
- avr/udivmodhi4.S
- avr/udivmodqi4.S
- bswapdi2.c
- bswapsi2.c
- bswapti2.c
- clzdi2.c
- clzsi2.c
- clzti2.c
- comparedf2.c
- comparesf2.c
- ctzdi2.c
- ctzsi2.c
- ctzti2.c
- divdf3.c
- divdi3.c
- divmoddi4.c
- divmodsi4.c
- divmodti4.c
- divsf3.c
- divsi3.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/divdi3.S
- i386/lshrdi3.S
- i386/moddi3.S
- i386/muldi3.S
- i386/udivdi3.S
- i386/umoddi3.S
- lshrdi3.c
- moddi3.c
- modsi3.c
- muldf3.c
- muldi3.c
- mulodi4.c
- mulosi4.c
- mulsf3.c
- powidf2.c
- powisf2.c
- riscv/muldi3.S
- riscv/mulsi3.S
- subdf3.c
- subsf3.c
- truncdfsf2.c
- udivdi3.c
- udivmoddi4.c
- udivmodsi4.c
- udivsi3.c
- umoddi3.c
- umodsi3.c
- x86_64/chkstk.S
这些内置函数需要支持128位整数。
- 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
这些内置函数需要支持正在Rust中添加的 f16
和 f128
。
- addtf3.c
- comparetf2.c
- divtf3.c
- extenddftf2.c
- extendhfsf2.c
- extendhftf2.c
- extendsftf2.c
- fixtfdi.c
- fixtfsi.c
- fixtfti.c
- fixunstfdi.c
- fixunstfsi.c
- fixunstfti.c
- floatditf.c
- floatsitf.c
- floattitf.c
- floatunditf.c
- floatunsitf.c
- floatuntitf.c
- multf3.c
- powitf2.c
- subtf3.c
- truncdfhf2.c
- truncsfhf2.c
- trunctfdf2.c
- trunctfhf2.c
- trunctfsf2.c
这些内置函数被Hexagon DSP使用。
- hexagon/common_entry_exit_abi1.S
- hexagon/common_entry_exit_abi2.S
- hexagon/common_entry_exit_legacy.S
- hexagon/dfaddsub.S~~
- hexagon/dfdiv.S~~
- hexagon/dffma.S~~
- hexagon/dfminmax.S~~
- hexagon/dfmul.S~~
- hexagon/dfsqrt.S~~
- hexagon/divdi3.S~~
- hexagon/divsi3.S~~
- hexagon/fastmath2_dlib_asm.S~~
- hexagon/fastmath2_ldlib_asm.S~~
- hexagon/fastmath_dlib_asm.S~~
- hexagon/memcpy_forward_vp4cp4n2.S~~
- hexagon/memcpy_likely_aligned.S~~
- hexagon/moddi3.S~~
- hexagon/modsi3.S~~
- hexagon/sfdiv_opt.S~~
- hexagon/sfsqrt_opt.S~~
- hexagon/udivdi3.S~~
- hexagon/udivmoddi4.S~~
- 六边形/udivmodsi4.S~~
- 六边形/udivsi3.S~~
- 六边形/umoddi3.S~~
- 六边形/umodsi3.S~~
未实现的功能
这些内建函数用于x87 f80
浮点数,这些浮点数在Rust中不受支持。
extendxftf2.cfixunsxfdi.cfixunsxfsi.cfixunsxfti.cfixxfdi.cfixxfti.cfloatdixf.cfloattixf.cfloatundixf.cfloatuntixf.ci386/floatdixf.Si386/floatundixf.Sx86_64/floatdixf.cx86_64/floatundixf.S
这些内建函数用于IBM "扩展双精度" 非IEEE 128位浮点数。
ppc/divtc3.cppc/fixtfdi.cppc/fixtfti.cppc/fixunstfdi.cppc/fixunstfti.cppc/floatditf.cppc/floattitf.cppc/floatunditf.cppc/gcc_qadd.cppc/gcc_qdiv.cppc/gcc_qmul.cppc/gcc_qsub.cppc/multc3.c
这些内建函数用于Rust不支持的不支持的16位大脑浮点数。
truncdfbf2.ctruncsfbf2.ctrunctfxf2.c
这些内建函数涉及Rust不支持的不支持的复数浮点类型。
divdc3.cdivsc3.cdivtc3.cdivxc3.cmuldc3.cmulsc3.cmultc3.cmulxc3.cpowixf2.c
这些内建函数从未被LLVM调用。
absvdi2.cabsvsi2.cabsvti2.caddvdi3.caddvsi3.caddvti3.carm/aeabi_cdcmp.Sarm/aeabi_cdcmpeq_check_nan.carm/aeabi_cfcmp.Sarm/aeabi_cfcmpeq_check_nan.carm/aeabi_div0.carm/aeabi_drsub.carm/aeabi_frsub.carm/aeabi_memcmp.Sarm/bswapdi2.Sarm/bswapsi2.Sarm/clzdi2.Sarm/clzsi2.Sarm/comparesf2.Sarm/restore_vfp_d8_d15_regs.Sarm/save_vfp_d8_d15_regs.Sarm/switch16.Sarm/switch32.Sarm/switch8.Sarm/switchu8.Scmpdi2.ccmpti2.cffssi2.cffsdi2.c- 这是由gcc调用的!ffsti2.cmulvdi3.cmulvsi3.cmulvti3.cnegdf2.cnegdi2.cnegsf2.cnegti2.cnegvdi2.cnegvsi2.cnegvti2.cparitydi2.cparitysi2.cparityti2.cpopcountdi2.cpopcountsi2.cpopcountti2.cppc/restFP.Sppc/saveFP.Ssubvdi3.csubvsi3.csubvti3.cucmpdi2.cucmpti2.cudivmodti4.c
Rust仅在支持它们的平台上公开原子类型,因此不需要回退到软件实现。
arm/sync_fetch_and_add_4.Sarm/sync_fetch_and_add_8.Sarm/sync_fetch_and_and_4.Sarm/sync_fetch_and_and_8.Sarm/sync_fetch_and_max_4.Sarm/sync_fetch_and_max_8.Sarm/sync_fetch_and_min_4.Sarm/sync_fetch_and_min_8.Sarm/sync_fetch_and_nand_4.Sarm/sync_fetch_and_nand_8.Sarm/sync_fetch_and_or_4.Sarm/sync_fetch_and_or_8.Sarm/sync_fetch_and_sub_4.Sarm/sync_fetch_and_sub_8.Sarm/sync_fetch_and_umax_4.Sarm/sync_fetch_and_umax_8.Sarm/sync_fetch_and_umin_4.Sarm/sync_fetch_and_umin_8.Sarm/sync_fetch_and_xor_4.Sarm/sync_fetch_and_xor_8.Sarm/sync_synchronize.Satomic.catomic_flag_clear.catomic_flag_clear_explicit.catomic_flag_test_and_set.catomic_flag_test_and_set_explicit.catomic_signal_fence.catomic_thread_fence.c
未使用Rust的杂项功能。
aarch64/fp_mode.caarch64/lse.S(LSE原子操作)aarch64/sme-abi-init.c(矩阵扩展)aarch64/sme-abi.S(矩阵扩展)aarch64/sme-libc-routines.c(矩阵扩展)apple_versioning.carm/fp_mode.cavr/exit.Sclear_cache.ccpu_model/aarch64.ccpu_model/x86.ccrtbegin.ccrtend.cemutls.cenable_execute_stack.ceprintf.cfp_mode.c(浮点异常处理)gcc_personality_v0.ci386/fp_mode.cint_util.cloongarch/fp_mode.cos_version_check.criscv/fp_mode.criscv/restore.S(调用者保存寄存器)riscv/save.S(调用者保存寄存器)trampoline_setup.cve/grow_stack.Sve/grow_stack_align.S
仅从软浮点代码中调用的内建函数的浮点实现。在这种情况下,最好简单地使用通用的软浮点版本。
i386/floatdidf.Si386/floatdisf.Si386/floatundidf.Si386/floatundisf.Sx86_64/floatundidf.Sx86_64/floatundisf.Sx86_64/floatdidf.cx86_64/floatdisf.c
许可证
编译器内建函数库crate同时受伊利诺伊大学“类似BSD”许可证和MIT许可证的双重授权。作为此代码的用户,您可以选择在任一许可证下使用它。作为贡献者,您同意允许您的代码在两种许可证下使用。
相关许可证的完整文本在LICENSE.TXT中。