From cf98161da7ed5217b6031796f0f60b4dd07148a4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 15 May 2019 12:57:36 -0700 Subject: [PATCH] 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. --- build.rs | 336 +++++++++++++++++++++++----------------------- ci/run.sh | 1 + src/float/conv.rs | 18 +-- src/int/mod.rs | 2 +- src/int/mul.rs | 2 +- src/int/sdiv.rs | 14 +- src/int/shift.rs | 6 +- src/int/udiv.rs | 18 +-- src/macros.rs | 23 ++-- 9 files changed, 198 insertions(+), 222 deletions(-) diff --git a/build.rs b/build.rs index a8301af..be5d42b 100644 --- a/build.rs +++ b/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"); diff --git a/ci/run.sh b/ci/run.sh index ae32806..4d6d6c6 100755 --- a/ci/run.sh +++ b/ci/run.sh @@ -1,5 +1,6 @@ set -ex +export CARGO_INCREMENTAL=0 cargo=cargo # Test our implementation diff --git a/src/float/conv.rs b/src/float/conv.rs index 21aac15..8a0fc6c 100644 --- a/src/float/conv.rs +++ b/src/float/conv.rs @@ -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) diff --git a/src/int/mod.rs b/src/int/mod.rs index fd1f0c3..7587bc6 100644 --- a/src/int/mod.rs +++ b/src/int/mod.rs @@ -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", diff --git a/src/int/mul.rs b/src/int/mul.rs index 376395a..8df58a2 100644 --- a/src/int/mul.rs +++ b/src/int/mul.rs @@ -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) diff --git a/src/int/sdiv.rs b/src/int/sdiv.rs index 4b63697..ad7f67b 100644 --- a/src/int/sdiv.rs +++ b/src/int/sdiv.rs @@ -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)) } diff --git a/src/int/shift.rs b/src/int/shift.rs index 4be588f..d986222 100644 --- a/src/int/shift.rs +++ b/src/int/shift.rs @@ -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) diff --git a/src/int/udiv.rs b/src/int/udiv.rs index 8837126..cdec11d 100644 --- a/src/int/udiv.rs +++ b/src/int/udiv.rs @@ -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; diff --git a/src/macros.rs b/src/macros.rs index e84338f..4abdae6 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -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 {