Merge pull request #293 from alexcrichton/deduplicate-cfg

Remove the need for #[cfg] in #[use_c_shim_if]
master
Alex Crichton 2019-05-15 16:45:18 -05:00 committed by GitHub
commit d9672420ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 198 additions and 222 deletions

336
build.rs
View File

@ -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");

View File

@ -1,5 +1,6 @@
set -ex set -ex
export CARGO_INCREMENTAL=0
cargo=cargo cargo=cargo
# Test our implementation # Test our implementation

View File

@ -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)

View File

@ -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",

View File

@ -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)

View File

@ -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))
} }

View File

@ -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)

View File

@ -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;

View File

@ -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 {