Browse Source

Merge pull request #293 from alexcrichton/deduplicate-cfg

Remove the need for #[cfg] in #[use_c_shim_if]
master
Alex Crichton 2 years ago
committed by GitHub
parent
commit
d9672420ab
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 336
      build.rs
  2. 1
      ci/run.sh
  3. 18
      src/float/conv.rs
  4. 2
      src/int/mod.rs
  5. 2
      src/int/mul.rs
  6. 14
      src/int/sdiv.rs
  7. 6
      src/int/shift.rs
  8. 18
      src/int/udiv.rs
  9. 23
      src/macros.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
ci/run.sh

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

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

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

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

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

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

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

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

Loading…
Cancel
Save