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