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:
Alex Crichton 2019-05-15 12:57:36 -07:00
parent 6178e2c611
commit cf98161da7
9 changed files with 198 additions and 222 deletions

334
build.rs
View File

@ -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_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.c",
"atomic_thread_fence.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");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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