Bläddra i källkod

Merge pull request #293 from alexcrichton/deduplicate-cfg

Remove the need for #[cfg] in #[use_c_shim_if]
Alex Crichton 6 år sedan
förälder
incheckning
d9672420ab
9 ändrade filer med 198 tillägg och 222 borttagningar
  1. 167 169
      build.rs
  2. 1 0
      ci/run.sh
  3. 4 14
      src/float/conv.rs
  4. 1 1
      src/int/mod.rs
  5. 1 1
      src/int/mul.rs
  6. 5 9
      src/int/sdiv.rs
  7. 3 3
      src/int/shift.rs
  8. 5 13
      src/int/udiv.rs
  9. 11 12
      src/macros.rs

+ 167 - 169
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 - 0
ci/run.sh

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

+ 4 - 14
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)

+ 1 - 1
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",

+ 1 - 1
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)

+ 5 - 9
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))
     }

+ 3 - 3
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)

+ 5 - 13
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;

+ 11 - 12
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 {