Remove the need for #[cfg] in #[use_c_shim_if]
This commit tweaks the implementation of the synthetic `#[use_c_shim_if]` attribute, renaming it to `#[maybe_use_optimized_c_shim]` in the process. This no longer requires specifying a `#[cfg]` clause indicating when the optimized intrinsic should be used, but rather this is inferred and printed from the build script. The build script will now print out appropriate `#[cfg]` directives for rustc to indicate what intrinsics it's compiling. This should remove the need for us to keep the build script and the source in sync, but rather the build script can simply take care of everything.
This commit is contained in:
parent
6178e2c611
commit
cf98161da7
336
build.rs
336
build.rs
@ -49,7 +49,6 @@ fn main() {
|
|||||||
if !target.contains("wasm32") && !target.contains("nvptx") && !target.starts_with("riscv") {
|
if !target.contains("wasm32") && !target.contains("nvptx") && !target.starts_with("riscv") {
|
||||||
#[cfg(feature = "c")]
|
#[cfg(feature = "c")]
|
||||||
c::compile(&llvm_target);
|
c::compile(&llvm_target);
|
||||||
println!("cargo:rustc-cfg=use_c");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,15 +90,14 @@ mod c {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extend(&mut self, sources: &[&'static str]) {
|
fn extend(&mut self, sources: &[(&'static str, &'static str)]) {
|
||||||
// NOTE Some intrinsics have both a generic implementation (e.g.
|
// NOTE Some intrinsics have both a generic implementation (e.g.
|
||||||
// `floatdidf.c`) and an arch optimized implementation
|
// `floatdidf.c`) and an arch optimized implementation
|
||||||
// (`x86_64/floatdidf.c`). In those cases, we keep the arch optimized
|
// (`x86_64/floatdidf.c`). In those cases, we keep the arch optimized
|
||||||
// implementation and discard the generic implementation. If we don't
|
// implementation and discard the generic implementation. If we don't
|
||||||
// and keep both implementations, the linker will yell at us about
|
// and keep both implementations, the linker will yell at us about
|
||||||
// duplicate symbols!
|
// duplicate symbols!
|
||||||
for &src in sources {
|
for (symbol, src) in sources {
|
||||||
let symbol = Path::new(src).file_stem().unwrap().to_str().unwrap();
|
|
||||||
if src.contains("/") {
|
if src.contains("/") {
|
||||||
// Arch-optimized implementation (preferred)
|
// Arch-optimized implementation (preferred)
|
||||||
self.map.insert(symbol, src);
|
self.map.insert(symbol, src);
|
||||||
@ -155,42 +153,42 @@ mod c {
|
|||||||
|
|
||||||
let mut sources = Sources::new();
|
let mut sources = Sources::new();
|
||||||
sources.extend(&[
|
sources.extend(&[
|
||||||
"absvdi2.c",
|
("__absvdi2", "absvdi2.c"),
|
||||||
"absvsi2.c",
|
("__absvsi2", "absvsi2.c"),
|
||||||
"addvdi3.c",
|
("__addvdi3", "addvdi3.c"),
|
||||||
"addvsi3.c",
|
("__addvsi3", "addvsi3.c"),
|
||||||
"apple_versioning.c",
|
("apple_versioning", "apple_versioning.c"),
|
||||||
"clzdi2.c",
|
("__clzdi2", "clzdi2.c"),
|
||||||
"clzsi2.c",
|
("__clzsi2", "clzsi2.c"),
|
||||||
"cmpdi2.c",
|
("__cmpdi2", "cmpdi2.c"),
|
||||||
"ctzdi2.c",
|
("__ctzdi2", "ctzdi2.c"),
|
||||||
"ctzsi2.c",
|
("__ctzsi2", "ctzsi2.c"),
|
||||||
"divdc3.c",
|
("__divdc3", "divdc3.c"),
|
||||||
"divsc3.c",
|
("__divsc3", "divsc3.c"),
|
||||||
"divxc3.c",
|
("__divxc3", "divxc3.c"),
|
||||||
"extendhfsf2.c",
|
("__extendhfsf2", "extendhfsf2.c"),
|
||||||
"int_util.c",
|
("__int_util", "int_util.c"),
|
||||||
"muldc3.c",
|
("__muldc3", "muldc3.c"),
|
||||||
"mulsc3.c",
|
("__mulsc3", "mulsc3.c"),
|
||||||
"mulvdi3.c",
|
("__mulvdi3", "mulvdi3.c"),
|
||||||
"mulvsi3.c",
|
("__mulvsi3", "mulvsi3.c"),
|
||||||
"mulxc3.c",
|
("__mulxc3", "mulxc3.c"),
|
||||||
"negdf2.c",
|
("__negdf2", "negdf2.c"),
|
||||||
"negdi2.c",
|
("__negdi2", "negdi2.c"),
|
||||||
"negsf2.c",
|
("__negsf2", "negsf2.c"),
|
||||||
"negvdi2.c",
|
("__negvdi2", "negvdi2.c"),
|
||||||
"negvsi2.c",
|
("__negvsi2", "negvsi2.c"),
|
||||||
"paritydi2.c",
|
("__paritydi2", "paritydi2.c"),
|
||||||
"paritysi2.c",
|
("__paritysi2", "paritysi2.c"),
|
||||||
"popcountdi2.c",
|
("__popcountdi2", "popcountdi2.c"),
|
||||||
"popcountsi2.c",
|
("__popcountsi2", "popcountsi2.c"),
|
||||||
"powixf2.c",
|
("__powixf2", "powixf2.c"),
|
||||||
"subvdi3.c",
|
("__subvdi3", "subvdi3.c"),
|
||||||
"subvsi3.c",
|
("__subvsi3", "subvsi3.c"),
|
||||||
"truncdfhf2.c",
|
("__truncdfhf2", "truncdfhf2.c"),
|
||||||
"truncdfsf2.c",
|
("__truncdfsf2", "truncdfsf2.c"),
|
||||||
"truncsfhf2.c",
|
("__truncsfhf2", "truncsfhf2.c"),
|
||||||
"ucmpdi2.c",
|
("__ucmpdi2", "ucmpdi2.c"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// When compiling in rustbuild (the rust-lang/rust repo) this library
|
// When compiling in rustbuild (the rust-lang/rust repo) this library
|
||||||
@ -198,43 +196,49 @@ mod c {
|
|||||||
// need, so include a few more that aren't typically needed by
|
// need, so include a few more that aren't typically needed by
|
||||||
// LLVM/Rust.
|
// LLVM/Rust.
|
||||||
if cfg!(feature = "rustbuild") {
|
if cfg!(feature = "rustbuild") {
|
||||||
sources.extend(&["ffsdi2.c"]);
|
sources.extend(&[("__ffsdi2", "ffsdi2.c")]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// On iOS and 32-bit OSX these are all just empty intrinsics, no need to
|
// On iOS and 32-bit OSX these are all just empty intrinsics, no need to
|
||||||
// include them.
|
// include them.
|
||||||
if target_os != "ios" && (target_vendor != "apple" || target_arch != "x86") {
|
if target_os != "ios" && (target_vendor != "apple" || target_arch != "x86") {
|
||||||
sources.extend(&[
|
sources.extend(&[
|
||||||
"absvti2.c",
|
("__absvti2", "absvti2.c"),
|
||||||
"addvti3.c",
|
("__addvti3", "addvti3.c"),
|
||||||
"clzti2.c",
|
("__clzti2", "clzti2.c"),
|
||||||
"cmpti2.c",
|
("__cmpti2", "cmpti2.c"),
|
||||||
"ctzti2.c",
|
("__ctzti2", "ctzti2.c"),
|
||||||
"ffsti2.c",
|
("__ffsti2", "ffsti2.c"),
|
||||||
"mulvti3.c",
|
("__mulvti3", "mulvti3.c"),
|
||||||
"negti2.c",
|
("__negti2", "negti2.c"),
|
||||||
"negvti2.c",
|
("__negvti2", "negvti2.c"),
|
||||||
"parityti2.c",
|
("__parityti2", "parityti2.c"),
|
||||||
"popcountti2.c",
|
("__popcountti2", "popcountti2.c"),
|
||||||
"subvti3.c",
|
("__subvti3", "subvti3.c"),
|
||||||
"ucmpti2.c",
|
("__ucmpti2", "ucmpti2.c"),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if target_vendor == "apple" {
|
if target_vendor == "apple" {
|
||||||
sources.extend(&[
|
sources.extend(&[
|
||||||
"atomic_flag_clear.c",
|
("atomic_flag_clear", "atomic_flag_clear.c"),
|
||||||
"atomic_flag_clear_explicit.c",
|
("atomic_flag_clear_explicit", "atomic_flag_clear_explicit.c"),
|
||||||
"atomic_flag_test_and_set.c",
|
("atomic_flag_test_and_set", "atomic_flag_test_and_set.c"),
|
||||||
"atomic_flag_test_and_set_explicit.c",
|
(
|
||||||
"atomic_signal_fence.c",
|
"atomic_flag_test_and_set_explicit",
|
||||||
"atomic_thread_fence.c",
|
"atomic_flag_test_and_set_explicit.c",
|
||||||
|
),
|
||||||
|
("atomic_signal_fence", "atomic_signal_fence.c"),
|
||||||
|
("atomic_thread_fence", "atomic_thread_fence.c"),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if target_env == "msvc" {
|
if target_env == "msvc" {
|
||||||
if target_arch == "x86_64" {
|
if target_arch == "x86_64" {
|
||||||
sources.extend(&["x86_64/floatdisf.c", "x86_64/floatdixf.c"]);
|
sources.extend(&[
|
||||||
|
("__floatdisf", "x86_64/floatdisf.c"),
|
||||||
|
("__floatdixf", "x86_64/floatdixf.c"),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// None of these seem to be used on x86_64 windows, and they've all
|
// None of these seem to be used on x86_64 windows, and they've all
|
||||||
@ -242,59 +246,59 @@ mod c {
|
|||||||
if target_os != "windows" {
|
if target_os != "windows" {
|
||||||
if target_arch == "x86_64" {
|
if target_arch == "x86_64" {
|
||||||
sources.extend(&[
|
sources.extend(&[
|
||||||
"x86_64/floatdisf.c",
|
("__floatdisf", "x86_64/floatdisf.c"),
|
||||||
"x86_64/floatdixf.c",
|
("__floatdixf", "x86_64/floatdixf.c"),
|
||||||
"x86_64/floatundidf.S",
|
("__floatundidf", "x86_64/floatundidf.S"),
|
||||||
"x86_64/floatundisf.S",
|
("__floatundisf", "x86_64/floatundisf.S"),
|
||||||
"x86_64/floatundixf.S",
|
("__floatundixf", "x86_64/floatundixf.S"),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if target_arch == "x86" {
|
if target_arch == "x86" {
|
||||||
sources.extend(&[
|
sources.extend(&[
|
||||||
"i386/ashldi3.S",
|
("__ashldi3", "i386/ashldi3.S"),
|
||||||
"i386/ashrdi3.S",
|
("__ashrdi3", "i386/ashrdi3.S"),
|
||||||
"i386/divdi3.S",
|
("__divdi3", "i386/divdi3.S"),
|
||||||
"i386/floatdidf.S",
|
("__floatdidf", "i386/floatdidf.S"),
|
||||||
"i386/floatdisf.S",
|
("__floatdisf", "i386/floatdisf.S"),
|
||||||
"i386/floatdixf.S",
|
("__floatdixf", "i386/floatdixf.S"),
|
||||||
"i386/floatundidf.S",
|
("__floatundidf", "i386/floatundidf.S"),
|
||||||
"i386/floatundisf.S",
|
("__floatundisf", "i386/floatundisf.S"),
|
||||||
"i386/floatundixf.S",
|
("__floatundixf", "i386/floatundixf.S"),
|
||||||
"i386/lshrdi3.S",
|
("__lshrdi3", "i386/lshrdi3.S"),
|
||||||
"i386/moddi3.S",
|
("__moddi3", "i386/moddi3.S"),
|
||||||
"i386/muldi3.S",
|
("__muldi3", "i386/muldi3.S"),
|
||||||
"i386/udivdi3.S",
|
("__udivdi3", "i386/udivdi3.S"),
|
||||||
"i386/umoddi3.S",
|
("__umoddi3", "i386/umoddi3.S"),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if target_arch == "arm" && target_os != "ios" && target_env != "msvc" {
|
if target_arch == "arm" && target_os != "ios" && target_env != "msvc" {
|
||||||
sources.extend(&[
|
sources.extend(&[
|
||||||
"arm/aeabi_div0.c",
|
("__aeabi_div0", "arm/aeabi_div0.c"),
|
||||||
"arm/aeabi_drsub.c",
|
("__aeabi_drsub", "arm/aeabi_drsub.c"),
|
||||||
"arm/aeabi_frsub.c",
|
("__aeabi_frsub", "arm/aeabi_frsub.c"),
|
||||||
"arm/bswapdi2.S",
|
("__bswapdi2", "arm/bswapdi2.S"),
|
||||||
"arm/bswapsi2.S",
|
("__bswapsi2", "arm/bswapsi2.S"),
|
||||||
"arm/clzdi2.S",
|
("__clzdi2", "arm/clzdi2.S"),
|
||||||
"arm/clzsi2.S",
|
("__clzsi2", "arm/clzsi2.S"),
|
||||||
"arm/divmodsi4.S",
|
("__divmodsi4", "arm/divmodsi4.S"),
|
||||||
"arm/divsi3.S",
|
("__divsi3", "arm/divsi3.S"),
|
||||||
"arm/modsi3.S",
|
("__modsi3", "arm/modsi3.S"),
|
||||||
"arm/switch16.S",
|
("__switch16", "arm/switch16.S"),
|
||||||
"arm/switch32.S",
|
("__switch32", "arm/switch32.S"),
|
||||||
"arm/switch8.S",
|
("__switch8", "arm/switch8.S"),
|
||||||
"arm/switchu8.S",
|
("__switchu8", "arm/switchu8.S"),
|
||||||
"arm/sync_synchronize.S",
|
("__sync_synchronize", "arm/sync_synchronize.S"),
|
||||||
"arm/udivmodsi4.S",
|
("__udivmodsi4", "arm/udivmodsi4.S"),
|
||||||
"arm/udivsi3.S",
|
("__udivsi3", "arm/udivsi3.S"),
|
||||||
"arm/umodsi3.S",
|
("__umodsi3", "arm/umodsi3.S"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if target_os == "freebsd" {
|
if target_os == "freebsd" {
|
||||||
sources.extend(&["clear_cache.c"]);
|
sources.extend(&[("__clear_cache", "clear_cache.c")]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// First of all aeabi_cdcmp and aeabi_cfcmp are never called by LLVM.
|
// First of all aeabi_cdcmp and aeabi_cfcmp are never called by LLVM.
|
||||||
@ -302,36 +306,36 @@ mod c {
|
|||||||
// Temporally workaround: exclude these files for big-endian targets.
|
// Temporally workaround: exclude these files for big-endian targets.
|
||||||
if !llvm_target[0].starts_with("thumbeb") && !llvm_target[0].starts_with("armeb") {
|
if !llvm_target[0].starts_with("thumbeb") && !llvm_target[0].starts_with("armeb") {
|
||||||
sources.extend(&[
|
sources.extend(&[
|
||||||
"arm/aeabi_cdcmp.S",
|
("__aeabi_cdcmp", "arm/aeabi_cdcmp.S"),
|
||||||
"arm/aeabi_cdcmpeq_check_nan.c",
|
("__aeabi_cdcmpeq_check_nan", "arm/aeabi_cdcmpeq_check_nan.c"),
|
||||||
"arm/aeabi_cfcmp.S",
|
("__aeabi_cfcmp", "arm/aeabi_cfcmp.S"),
|
||||||
"arm/aeabi_cfcmpeq_check_nan.c",
|
("__aeabi_cfcmpeq_check_nan", "arm/aeabi_cfcmpeq_check_nan.c"),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if llvm_target[0] == "armv7" {
|
if llvm_target[0] == "armv7" {
|
||||||
sources.extend(&[
|
sources.extend(&[
|
||||||
"arm/sync_fetch_and_add_4.S",
|
("__sync_fetch_and_add_4", "arm/sync_fetch_and_add_4.S"),
|
||||||
"arm/sync_fetch_and_add_8.S",
|
("__sync_fetch_and_add_8", "arm/sync_fetch_and_add_8.S"),
|
||||||
"arm/sync_fetch_and_and_4.S",
|
("__sync_fetch_and_and_4", "arm/sync_fetch_and_and_4.S"),
|
||||||
"arm/sync_fetch_and_and_8.S",
|
("__sync_fetch_and_and_8", "arm/sync_fetch_and_and_8.S"),
|
||||||
"arm/sync_fetch_and_max_4.S",
|
("__sync_fetch_and_max_4", "arm/sync_fetch_and_max_4.S"),
|
||||||
"arm/sync_fetch_and_max_8.S",
|
("__sync_fetch_and_max_8", "arm/sync_fetch_and_max_8.S"),
|
||||||
"arm/sync_fetch_and_min_4.S",
|
("__sync_fetch_and_min_4", "arm/sync_fetch_and_min_4.S"),
|
||||||
"arm/sync_fetch_and_min_8.S",
|
("__sync_fetch_and_min_8", "arm/sync_fetch_and_min_8.S"),
|
||||||
"arm/sync_fetch_and_nand_4.S",
|
("__sync_fetch_and_nand_4", "arm/sync_fetch_and_nand_4.S"),
|
||||||
"arm/sync_fetch_and_nand_8.S",
|
("__sync_fetch_and_nand_8", "arm/sync_fetch_and_nand_8.S"),
|
||||||
"arm/sync_fetch_and_or_4.S",
|
("__sync_fetch_and_or_4", "arm/sync_fetch_and_or_4.S"),
|
||||||
"arm/sync_fetch_and_or_8.S",
|
("__sync_fetch_and_or_8", "arm/sync_fetch_and_or_8.S"),
|
||||||
"arm/sync_fetch_and_sub_4.S",
|
("__sync_fetch_and_sub_4", "arm/sync_fetch_and_sub_4.S"),
|
||||||
"arm/sync_fetch_and_sub_8.S",
|
("__sync_fetch_and_sub_8", "arm/sync_fetch_and_sub_8.S"),
|
||||||
"arm/sync_fetch_and_umax_4.S",
|
("__sync_fetch_and_umax_4", "arm/sync_fetch_and_umax_4.S"),
|
||||||
"arm/sync_fetch_and_umax_8.S",
|
("__sync_fetch_and_umax_8", "arm/sync_fetch_and_umax_8.S"),
|
||||||
"arm/sync_fetch_and_umin_4.S",
|
("__sync_fetch_and_umin_4", "arm/sync_fetch_and_umin_4.S"),
|
||||||
"arm/sync_fetch_and_umin_8.S",
|
("__sync_fetch_and_umin_8", "arm/sync_fetch_and_umin_8.S"),
|
||||||
"arm/sync_fetch_and_xor_4.S",
|
("__sync_fetch_and_xor_4", "arm/sync_fetch_and_xor_4.S"),
|
||||||
"arm/sync_fetch_and_xor_8.S",
|
("__sync_fetch_and_xor_8", "arm/sync_fetch_and_xor_8.S"),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,73 +349,66 @@ mod c {
|
|||||||
// do not support double precision floating points conversions so the files
|
// do not support double precision floating points conversions so the files
|
||||||
// that include such instructions are not included for these targets.
|
// that include such instructions are not included for these targets.
|
||||||
sources.extend(&[
|
sources.extend(&[
|
||||||
"arm/fixdfsivfp.S",
|
("__fixdfsivfp", "arm/fixdfsivfp.S"),
|
||||||
"arm/fixunsdfsivfp.S",
|
("__fixunsdfsivfp", "arm/fixunsdfsivfp.S"),
|
||||||
"arm/floatsidfvfp.S",
|
("__floatsidfvfp", "arm/floatsidfvfp.S"),
|
||||||
"arm/floatunssidfvfp.S",
|
("__floatunssidfvfp", "arm/floatunssidfvfp.S"),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
sources.extend(&[
|
sources.extend(&[
|
||||||
"arm/fixsfsivfp.S",
|
("__fixsfsivfp", "arm/fixsfsivfp.S"),
|
||||||
"arm/fixunssfsivfp.S",
|
("__fixunssfsivfp", "arm/fixunssfsivfp.S"),
|
||||||
"arm/floatsisfvfp.S",
|
("__floatsisfvfp", "arm/floatsisfvfp.S"),
|
||||||
"arm/floatunssisfvfp.S",
|
("__floatunssisfvfp", "arm/floatunssisfvfp.S"),
|
||||||
"arm/floatunssisfvfp.S",
|
("__floatunssisfvfp", "arm/floatunssisfvfp.S"),
|
||||||
"arm/restore_vfp_d8_d15_regs.S",
|
("__restore_vfp_d8_d15_regs", "arm/restore_vfp_d8_d15_regs.S"),
|
||||||
"arm/save_vfp_d8_d15_regs.S",
|
("__save_vfp_d8_d15_regs", "arm/save_vfp_d8_d15_regs.S"),
|
||||||
"arm/negdf2vfp.S",
|
("__negdf2vfp", "arm/negdf2vfp.S"),
|
||||||
"arm/negsf2vfp.S",
|
("__negsf2vfp", "arm/negsf2vfp.S"),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if target_arch == "aarch64" {
|
if target_arch == "aarch64" {
|
||||||
sources.extend(&[
|
sources.extend(&[
|
||||||
"comparetf2.c",
|
("__comparetf2", "comparetf2.c"),
|
||||||
"extenddftf2.c",
|
("__extenddftf2", "extenddftf2.c"),
|
||||||
"extendsftf2.c",
|
("__extendsftf2", "extendsftf2.c"),
|
||||||
"fixtfdi.c",
|
("__fixtfdi", "fixtfdi.c"),
|
||||||
"fixtfsi.c",
|
("__fixtfsi", "fixtfsi.c"),
|
||||||
"fixtfti.c",
|
("__fixtfti", "fixtfti.c"),
|
||||||
"fixunstfdi.c",
|
("__fixunstfdi", "fixunstfdi.c"),
|
||||||
"fixunstfsi.c",
|
("__fixunstfsi", "fixunstfsi.c"),
|
||||||
"fixunstfti.c",
|
("__fixunstfti", "fixunstfti.c"),
|
||||||
"floatditf.c",
|
("__floatditf", "floatditf.c"),
|
||||||
"floatsitf.c",
|
("__floatsitf", "floatsitf.c"),
|
||||||
"floatunditf.c",
|
("__floatunditf", "floatunditf.c"),
|
||||||
"floatunsitf.c",
|
("__floatunsitf", "floatunsitf.c"),
|
||||||
"trunctfdf2.c",
|
("__trunctfdf2", "trunctfdf2.c"),
|
||||||
"trunctfsf2.c",
|
("__trunctfsf2", "trunctfsf2.c"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if target_os != "windows" {
|
if target_os != "windows" {
|
||||||
sources.extend(&["multc3.c"]);
|
sources.extend(&[("__multc3", "multc3.c")]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the assembly implementations that won't compile for the target
|
// Remove the assembly implementations that won't compile for the target
|
||||||
if llvm_target[0] == "thumbv6m" || llvm_target[0] == "thumbv8m.base" {
|
if llvm_target[0] == "thumbv6m" || llvm_target[0] == "thumbv8m.base" {
|
||||||
sources.remove(&[
|
let mut to_remove = Vec::new();
|
||||||
"clzdi2",
|
for (k, v) in sources.map.iter() {
|
||||||
"clzsi2",
|
if v.ends_with(".S") {
|
||||||
"divmodsi4",
|
to_remove.push(*k);
|
||||||
"divsi3",
|
}
|
||||||
"modsi3",
|
}
|
||||||
"switch16",
|
sources.remove(&to_remove);
|
||||||
"switch32",
|
|
||||||
"switch8",
|
|
||||||
"switchu8",
|
|
||||||
"udivmodsi4",
|
|
||||||
"udivsi3",
|
|
||||||
"umodsi3",
|
|
||||||
]);
|
|
||||||
|
|
||||||
// But use some generic implementations where possible
|
// But use some generic implementations where possible
|
||||||
sources.extend(&["clzdi2.c", "clzsi2.c"])
|
sources.extend(&[("__clzdi2", "clzdi2.c"), ("__clzsi2", "clzsi2.c")])
|
||||||
}
|
}
|
||||||
|
|
||||||
if llvm_target[0] == "thumbv7m" || llvm_target[0] == "thumbv7em" {
|
if llvm_target[0] == "thumbv7m" || llvm_target[0] == "thumbv7em" {
|
||||||
sources.remove(&["aeabi_cdcmp", "aeabi_cfcmp"]);
|
sources.remove(&["__aeabi_cdcmp", "__aeabi_cfcmp"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When compiling in rustbuild (the rust-lang/rust repo) this build
|
// When compiling in rustbuild (the rust-lang/rust repo) this build
|
||||||
@ -423,10 +420,11 @@ mod c {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let src_dir = root.join("compiler-rt/lib/builtins");
|
let src_dir = root.join("compiler-rt/lib/builtins");
|
||||||
for src in sources.map.values() {
|
for (sym, src) in sources.map.iter() {
|
||||||
let src = src_dir.join(src);
|
let src = src_dir.join(src);
|
||||||
cfg.file(&src);
|
cfg.file(&src);
|
||||||
println!("cargo:rerun-if-changed={}", src.display());
|
println!("cargo:rerun-if-changed={}", src.display());
|
||||||
|
println!("cargo:rustc-cfg={}=\"optimized-c\"", sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.compile("libcompiler-rt.a");
|
cfg.compile("libcompiler-rt.a");
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
set -ex
|
set -ex
|
||||||
|
|
||||||
|
export CARGO_INCREMENTAL=0
|
||||||
cargo=cargo
|
cargo=cargo
|
||||||
|
|
||||||
# Test our implementation
|
# Test our implementation
|
||||||
|
@ -87,11 +87,7 @@ intrinsics! {
|
|||||||
int_to_float!(i, i32, f64)
|
int_to_float!(i, i32, f64)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[use_c_shim_if(any(
|
#[maybe_use_optimized_c_shim]
|
||||||
all(target_arch = "x86", not(target_env = "msvc")),
|
|
||||||
all(target_arch = "x86_64", not(windows)),
|
|
||||||
all(target_arch = "x86_64", target_env = "msvc"),
|
|
||||||
))]
|
|
||||||
#[arm_aeabi_alias = __aeabi_l2f]
|
#[arm_aeabi_alias = __aeabi_l2f]
|
||||||
pub extern "C" fn __floatdisf(i: i64) -> f32 {
|
pub extern "C" fn __floatdisf(i: i64) -> f32 {
|
||||||
// On x86_64 LLVM will use native instructions for this conversion, we
|
// On x86_64 LLVM will use native instructions for this conversion, we
|
||||||
@ -103,7 +99,7 @@ intrinsics! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
|
#[maybe_use_optimized_c_shim]
|
||||||
#[arm_aeabi_alias = __aeabi_l2d]
|
#[arm_aeabi_alias = __aeabi_l2d]
|
||||||
pub extern "C" fn __floatdidf(i: i64) -> f64 {
|
pub extern "C" fn __floatdidf(i: i64) -> f64 {
|
||||||
// On x86_64 LLVM will use native instructions for this conversion, we
|
// On x86_64 LLVM will use native instructions for this conversion, we
|
||||||
@ -135,19 +131,13 @@ intrinsics! {
|
|||||||
int_to_float!(i, u32, f64)
|
int_to_float!(i, u32, f64)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[use_c_shim_if(any(
|
#[maybe_use_optimized_c_shim]
|
||||||
all(target_arch = "x86", not(target_env = "msvc")),
|
|
||||||
all(target_arch = "x86_64", not(windows)),
|
|
||||||
))]
|
|
||||||
#[arm_aeabi_alias = __aeabi_ul2f]
|
#[arm_aeabi_alias = __aeabi_ul2f]
|
||||||
pub extern "C" fn __floatundisf(i: u64) -> f32 {
|
pub extern "C" fn __floatundisf(i: u64) -> f32 {
|
||||||
int_to_float!(i, u64, f32)
|
int_to_float!(i, u64, f32)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[use_c_shim_if(any(
|
#[maybe_use_optimized_c_shim]
|
||||||
all(target_arch = "x86", not(target_env = "msvc")),
|
|
||||||
all(target_arch = "x86_64", not(windows)),
|
|
||||||
))]
|
|
||||||
#[arm_aeabi_alias = __aeabi_ul2d]
|
#[arm_aeabi_alias = __aeabi_ul2d]
|
||||||
pub extern "C" fn __floatundidf(i: u64) -> f64 {
|
pub extern "C" fn __floatundidf(i: u64) -> f64 {
|
||||||
int_to_float!(i, u64, f64)
|
int_to_float!(i, u64, f64)
|
||||||
|
@ -302,7 +302,7 @@ impl_wide_int!(u32, u64, 32);
|
|||||||
impl_wide_int!(u64, u128, 64);
|
impl_wide_int!(u64, u128, 64);
|
||||||
|
|
||||||
intrinsics! {
|
intrinsics! {
|
||||||
#[use_c_shim_if(/* always if C compilation is enabled */)]
|
#[maybe_use_optimized_c_shim]
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_pointer_width = "16",
|
target_pointer_width = "16",
|
||||||
target_pointer_width = "32",
|
target_pointer_width = "32",
|
||||||
|
@ -84,7 +84,7 @@ trait UMulo: Int {
|
|||||||
impl UMulo for u128 {}
|
impl UMulo for u128 {}
|
||||||
|
|
||||||
intrinsics! {
|
intrinsics! {
|
||||||
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
|
#[maybe_use_optimized_c_shim]
|
||||||
#[arm_aeabi_alias = __aeabi_lmul]
|
#[arm_aeabi_alias = __aeabi_lmul]
|
||||||
pub extern "C" fn __muldi3(a: u64, b: u64) -> u64 {
|
pub extern "C" fn __muldi3(a: u64, b: u64) -> u64 {
|
||||||
a.mul(b)
|
a.mul(b)
|
||||||
|
@ -58,13 +58,13 @@ impl Divmod for i32 {}
|
|||||||
impl Divmod for i64 {}
|
impl Divmod for i64 {}
|
||||||
|
|
||||||
intrinsics! {
|
intrinsics! {
|
||||||
#[use_c_shim_if(all(target_arch = "arm", not(target_os = "ios"), not(thumb_1)))]
|
#[maybe_use_optimized_c_shim]
|
||||||
#[arm_aeabi_alias = __aeabi_idiv]
|
#[arm_aeabi_alias = __aeabi_idiv]
|
||||||
pub extern "C" fn __divsi3(a: i32, b: i32) -> i32 {
|
pub extern "C" fn __divsi3(a: i32, b: i32) -> i32 {
|
||||||
a.div(b)
|
a.div(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
|
#[maybe_use_optimized_c_shim]
|
||||||
pub extern "C" fn __divdi3(a: i64, b: i64) -> i64 {
|
pub extern "C" fn __divdi3(a: i64, b: i64) -> i64 {
|
||||||
a.div(b)
|
a.div(b)
|
||||||
}
|
}
|
||||||
@ -74,15 +74,12 @@ intrinsics! {
|
|||||||
a.div(b)
|
a.div(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[use_c_shim_if(all(target_arch = "arm",
|
#[maybe_use_optimized_c_shim]
|
||||||
not(target_os = "ios"),
|
|
||||||
not(target_env = "msvc"),
|
|
||||||
not(thumb_1)))]
|
|
||||||
pub extern "C" fn __modsi3(a: i32, b: i32) -> i32 {
|
pub extern "C" fn __modsi3(a: i32, b: i32) -> i32 {
|
||||||
a.mod_(b)
|
a.mod_(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
|
#[maybe_use_optimized_c_shim]
|
||||||
pub extern "C" fn __moddi3(a: i64, b: i64) -> i64 {
|
pub extern "C" fn __moddi3(a: i64, b: i64) -> i64 {
|
||||||
a.mod_(b)
|
a.mod_(b)
|
||||||
}
|
}
|
||||||
@ -92,8 +89,7 @@ intrinsics! {
|
|||||||
a.mod_(b)
|
a.mod_(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[use_c_shim_if(all(target_arch = "arm", not(target_env = "msvc"),
|
#[maybe_use_optimized_c_shim]
|
||||||
not(target_os = "ios"), not(thumb_1)))]
|
|
||||||
pub extern "C" fn __divmodsi4(a: i32, b: i32, rem: &mut i32) -> i32 {
|
pub extern "C" fn __divmodsi4(a: i32, b: i32, rem: &mut i32) -> i32 {
|
||||||
a.divmod(b, rem, |a, b| __divsi3(a, b))
|
a.divmod(b, rem, |a, b| __divsi3(a, b))
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ impl Lshr for u64 {}
|
|||||||
impl Lshr for u128 {}
|
impl Lshr for u128 {}
|
||||||
|
|
||||||
intrinsics! {
|
intrinsics! {
|
||||||
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
|
#[maybe_use_optimized_c_shim]
|
||||||
#[arm_aeabi_alias = __aeabi_llsl]
|
#[arm_aeabi_alias = __aeabi_llsl]
|
||||||
pub extern "C" fn __ashldi3(a: u64, b: u32) -> u64 {
|
pub extern "C" fn __ashldi3(a: u64, b: u32) -> u64 {
|
||||||
a.ashl(b)
|
a.ashl(b)
|
||||||
@ -84,7 +84,7 @@ intrinsics! {
|
|||||||
a.ashl(b)
|
a.ashl(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
|
#[maybe_use_optimized_c_shim]
|
||||||
#[arm_aeabi_alias = __aeabi_lasr]
|
#[arm_aeabi_alias = __aeabi_lasr]
|
||||||
pub extern "C" fn __ashrdi3(a: i64, b: u32) -> i64 {
|
pub extern "C" fn __ashrdi3(a: i64, b: u32) -> i64 {
|
||||||
a.ashr(b)
|
a.ashr(b)
|
||||||
@ -94,7 +94,7 @@ intrinsics! {
|
|||||||
a.ashr(b)
|
a.ashr(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
|
#[maybe_use_optimized_c_shim]
|
||||||
#[arm_aeabi_alias = __aeabi_llsr]
|
#[arm_aeabi_alias = __aeabi_llsr]
|
||||||
pub extern "C" fn __lshrdi3(a: u64, b: u32) -> u64 {
|
pub extern "C" fn __lshrdi3(a: u64, b: u32) -> u64 {
|
||||||
a.lshr(b)
|
a.lshr(b)
|
||||||
|
@ -152,9 +152,7 @@ macro_rules! udivmod_inner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
intrinsics! {
|
intrinsics! {
|
||||||
#[use_c_shim_if(all(target_arch = "arm",
|
#[maybe_use_optimized_c_shim]
|
||||||
not(target_os = "ios"),
|
|
||||||
not(thumb_1)))]
|
|
||||||
#[arm_aeabi_alias = __aeabi_uidiv]
|
#[arm_aeabi_alias = __aeabi_uidiv]
|
||||||
/// Returns `n / d`
|
/// Returns `n / d`
|
||||||
pub extern "C" fn __udivsi3(n: u32, d: u32) -> u32 {
|
pub extern "C" fn __udivsi3(n: u32, d: u32) -> u32 {
|
||||||
@ -212,20 +210,14 @@ intrinsics! {
|
|||||||
(q << 1) | carry
|
(q << 1) | carry
|
||||||
}
|
}
|
||||||
|
|
||||||
#[use_c_shim_if(all(target_arch = "arm",
|
#[maybe_use_optimized_c_shim]
|
||||||
not(target_os = "ios"),
|
|
||||||
not(target_env = "msvc"),
|
|
||||||
not(thumb_1)))]
|
|
||||||
/// Returns `n % d`
|
/// Returns `n % d`
|
||||||
pub extern "C" fn __umodsi3(n: u32, d: u32) -> u32 {
|
pub extern "C" fn __umodsi3(n: u32, d: u32) -> u32 {
|
||||||
let q = __udivsi3(n, d);
|
let q = __udivsi3(n, d);
|
||||||
n - q * d
|
n - q * d
|
||||||
}
|
}
|
||||||
|
|
||||||
#[use_c_shim_if(all(target_arch = "arm",
|
#[maybe_use_optimized_c_shim]
|
||||||
not(target_os = "ios"),
|
|
||||||
not(target_env = "msvc"),
|
|
||||||
not(thumb_1)))]
|
|
||||||
/// Returns `n / d` and sets `*rem = n % d`
|
/// Returns `n / d` and sets `*rem = n % d`
|
||||||
pub extern "C" fn __udivmodsi4(n: u32, d: u32, rem: Option<&mut u32>) -> u32 {
|
pub extern "C" fn __udivmodsi4(n: u32, d: u32, rem: Option<&mut u32>) -> u32 {
|
||||||
let q = __udivsi3(n, d);
|
let q = __udivsi3(n, d);
|
||||||
@ -235,13 +227,13 @@ intrinsics! {
|
|||||||
q
|
q
|
||||||
}
|
}
|
||||||
|
|
||||||
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
|
#[maybe_use_optimized_c_shim]
|
||||||
/// Returns `n / d`
|
/// Returns `n / d`
|
||||||
pub extern "C" fn __udivdi3(n: u64, d: u64) -> u64 {
|
pub extern "C" fn __udivdi3(n: u64, d: u64) -> u64 {
|
||||||
__udivmoddi4(n, d, None)
|
__udivmoddi4(n, d, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[use_c_shim_if(all(target_arch = "x86", not(target_env = "msvc")))]
|
#[maybe_use_optimized_c_shim]
|
||||||
/// Returns `n % d`
|
/// Returns `n % d`
|
||||||
pub extern "C" fn __umoddi3(n: u64, d: u64) -> u64 {
|
pub extern "C" fn __umoddi3(n: u64, d: u64) -> u64 {
|
||||||
let mut rem = 0;
|
let mut rem = 0;
|
||||||
|
@ -30,8 +30,8 @@
|
|||||||
///
|
///
|
||||||
/// A quick overview of attributes supported right now are:
|
/// A quick overview of attributes supported right now are:
|
||||||
///
|
///
|
||||||
/// * `use_c_shim_if` - takes a #[cfg] directive and falls back to the
|
/// * `maybe_use_optimized_c_shim` - indicates that the Rust implementation is
|
||||||
/// C-compiled version if `use_c` is specified.
|
/// ignored if an optimized C version was compiled.
|
||||||
/// * `aapcs_on_arm` - forces the ABI of the function to be `"aapcs"` on ARM and
|
/// * `aapcs_on_arm` - forces the ABI of the function to be `"aapcs"` on ARM and
|
||||||
/// the specified ABI everywhere else.
|
/// the specified ABI everywhere else.
|
||||||
/// * `unadjusted_on_win64` - like `aapcs_on_arm` this switches to the
|
/// * `unadjusted_on_win64` - like `aapcs_on_arm` this switches to the
|
||||||
@ -51,15 +51,14 @@ macro_rules! intrinsics {
|
|||||||
// to the architecture-specific versions which should be more optimized. The
|
// to the architecture-specific versions which should be more optimized. The
|
||||||
// purpose of this macro is to easily allow specifying this.
|
// purpose of this macro is to easily allow specifying this.
|
||||||
//
|
//
|
||||||
// The argument to `use_c_shim_if` is a `#[cfg]` directive which, when true,
|
// The `#[maybe_use_optimized_c_shim]` attribute indicates that this
|
||||||
// will cause this crate's exported version of `$name` to just redirect to
|
// intrinsic may have an optimized C version. In these situations the build
|
||||||
// the C implementation. No symbol named `$name` will be in the object file
|
// script, if the C code is enabled and compiled, will emit a cfg directive
|
||||||
// for this crate itself.
|
// to get passed to rustc for our compilation. If that cfg is set we skip
|
||||||
//
|
// the Rust implementation, but if the attribute is not enabled then we
|
||||||
// When the `#[cfg]` directive is false, or when the `c` feature is
|
// compile in the Rust implementation.
|
||||||
// disabled, the provided implementation is used instead.
|
|
||||||
(
|
(
|
||||||
#[use_c_shim_if($($cfg_clause:tt)*)]
|
#[maybe_use_optimized_c_shim]
|
||||||
$(#[$($attr:tt)*])*
|
$(#[$($attr:tt)*])*
|
||||||
pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty {
|
pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) -> $ret:ty {
|
||||||
$($body:tt)*
|
$($body:tt)*
|
||||||
@ -68,7 +67,7 @@ macro_rules! intrinsics {
|
|||||||
$($rest:tt)*
|
$($rest:tt)*
|
||||||
) => (
|
) => (
|
||||||
|
|
||||||
#[cfg(all(use_c, $($cfg_clause)*))]
|
#[cfg($name = "optimized-c")]
|
||||||
pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
|
pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
|
||||||
extern $abi {
|
extern $abi {
|
||||||
fn $name($($argname: $ty),*) -> $ret;
|
fn $name($($argname: $ty),*) -> $ret;
|
||||||
@ -78,7 +77,7 @@ macro_rules! intrinsics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(all(use_c, $($cfg_clause)*)))]
|
#[cfg(not($name = "optimized-c"))]
|
||||||
intrinsics! {
|
intrinsics! {
|
||||||
$(#[$($attr)*])*
|
$(#[$($attr)*])*
|
||||||
pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
|
pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
|
||||||
|
Loading…
Reference in New Issue
Block a user