diff --git a/build.rs b/build.rs index 5d555d6..835b423 100644 --- a/build.rs +++ b/build.rs @@ -50,10 +50,11 @@ fn main() { println!("cargo:rustc-cfg=thumb") } - // compiler-rt `cfg`s away some intrinsics for thumbv6m because that target doesn't have full - // THUMBv2 support. We have to cfg our code accordingly. - if llvm_target[0] == "thumbv6m" { - println!("cargo:rustc-cfg=thumbv6m") + // compiler-rt `cfg`s away some intrinsics for thumbv6m and thumbv8m.base because + // these targets do not have full Thumb-2 support but only original Thumb-1. + // We have to cfg our code accordingly. + if llvm_target[0] == "thumbv6m" || llvm_target[0] == "thumbv8m.base" { + println!("cargo:rustc-cfg=thumb_1") } // Only emit the ARM Linux atomic emulation on pre-ARMv6 architectures. @@ -360,24 +361,36 @@ mod c { } if llvm_target.last().unwrap().ends_with("eabihf") { - if !llvm_target[0].starts_with("thumbv7em") { + if !llvm_target[0].starts_with("thumbv7em") && + !llvm_target[0].starts_with("thumbv8m.main") { + // The FPU option chosen for these architectures in cc-rs, ie: + // -mfpu=fpv4-sp-d16 for thumbv7em + // -mfpu=fpv5-sp-d16 for thumbv8m.main + // 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/fixsfsivfp.S", "arm/fixunsdfsivfp.S", - "arm/fixunssfsivfp.S", "arm/floatsidfvfp.S", - "arm/floatsisfvfp.S", "arm/floatunssidfvfp.S", - "arm/floatunssisfvfp.S", - "arm/restore_vfp_d8_d15_regs.S", - "arm/save_vfp_d8_d15_regs.S", ], ); } - sources.extend(&["arm/negdf2vfp.S", "arm/negsf2vfp.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", + ] + ); } @@ -408,7 +421,7 @@ mod c { } // Remove the assembly implementations that won't compile for the target - if llvm_target[0] == "thumbv6m" { + if llvm_target[0] == "thumbv6m" || llvm_target[0] == "thumbv8m.base" { sources.remove( &[ "clzdi2", diff --git a/examples/intrinsics.rs b/examples/intrinsics.rs index c52b4f0..89c2c23 100644 --- a/examples/intrinsics.rs +++ b/examples/intrinsics.rs @@ -19,9 +19,6 @@ extern crate panic_handler; #[link(name = "c")] extern {} -// NOTE cfg(not(thumbv6m)) means that the operation is not supported on ARMv6-M at all. Not even -// compiler-rt provides a C/assembly implementation. - // Every function in this module maps will be lowered to an intrinsic by LLVM, if the platform // doesn't have native support for the operation used in the function. ARM has a naming convention // convention for its intrinsics that's different from other architectures; that's why some function @@ -39,70 +36,40 @@ mod intrinsics { } // fixdfdi - #[cfg(not(thumbv6m))] pub fn aeabi_d2l(x: f64) -> i64 { x as i64 } - #[cfg(thumbv6m)] - pub fn aeabi_d2l(_: f64) -> i64 { - 0 - } - // fixunsdfsi pub fn aeabi_d2uiz(x: f64) -> u32 { x as u32 } // fixunsdfdi - #[cfg(not(thumbv6m))] pub fn aeabi_d2ulz(x: f64) -> u64 { x as u64 } - #[cfg(thumbv6m)] - pub fn aeabi_d2ulz(_: f64) -> u64 { - 0 - } - // adddf3 pub fn aeabi_dadd(a: f64, b: f64) -> f64 { a + b } // eqdf2 - #[cfg(not(thumbv6m))] pub fn aeabi_dcmpeq(a: f64, b: f64) -> bool { a == b } - #[cfg(thumbv6m)] - pub fn aeabi_dcmpeq(_: f64, _: f64) -> bool { - true - } - // gtdf2 - #[cfg(not(thumbv6m))] pub fn aeabi_dcmpgt(a: f64, b: f64) -> bool { a > b } - #[cfg(thumbv6m)] - pub fn aeabi_dcmpgt(_: f64, _: f64) -> bool { - true - } - // ltdf2 - #[cfg(not(thumbv6m))] pub fn aeabi_dcmplt(a: f64, b: f64) -> bool { a < b } - #[cfg(thumbv6m)] - pub fn aeabi_dcmplt(_: f64, _: f64) -> bool { - true - } - // divdf3 pub fn aeabi_ddiv(a: f64, b: f64) -> f64 { a / b @@ -129,70 +96,40 @@ mod intrinsics { } // fixsfdi - #[cfg(not(thumbv6m))] pub fn aeabi_f2lz(x: f32) -> i64 { x as i64 } - #[cfg(thumbv6m)] - pub fn aeabi_f2lz(_: f32) -> i64 { - 0 - } - // fixunssfsi pub fn aeabi_f2uiz(x: f32) -> u32 { x as u32 } // fixunssfdi - #[cfg(not(thumbv6m))] pub fn aeabi_f2ulz(x: f32) -> u64 { x as u64 } - #[cfg(thumbv6m)] - pub fn aeabi_f2ulz(_: f32) -> u64 { - 0 - } - // addsf3 pub fn aeabi_fadd(a: f32, b: f32) -> f32 { a + b } // eqsf2 - #[cfg(not(thumbv6m))] pub fn aeabi_fcmpeq(a: f32, b: f32) -> bool { a == b } - #[cfg(thumbv6m)] - pub fn aeabi_fcmpeq(_: f32, _: f32) -> bool { - true - } - // gtsf2 - #[cfg(not(thumbv6m))] pub fn aeabi_fcmpgt(a: f32, b: f32) -> bool { a > b } - #[cfg(thumbv6m)] - pub fn aeabi_fcmpgt(_: f32, _: f32) -> bool { - true - } - // ltsf2 - #[cfg(not(thumbv6m))] pub fn aeabi_fcmplt(a: f32, b: f32) -> bool { a < b } - #[cfg(thumbv6m)] - pub fn aeabi_fcmplt(_: f32, _: f32) -> bool { - true - } - // divsf3 pub fn aeabi_fdiv(a: f32, b: f32) -> f32 { a / b diff --git a/src/int/sdiv.rs b/src/int/sdiv.rs index 89bb51a..a2e8aa9 100644 --- a/src/int/sdiv.rs +++ b/src/int/sdiv.rs @@ -74,8 +74,8 @@ intrinsics! { #[use_c_shim_if(all(target_arch = "arm", not(target_os = "ios"), - not(target_env = "msvc")), - not(thumbv6m))] + not(target_env = "msvc"), + not(thumb_1)))] pub extern "C" fn __modsi3(a: i32, b: i32) -> i32 { a.mod_(b) } @@ -91,7 +91,7 @@ intrinsics! { } #[use_c_shim_if(all(target_arch = "arm", not(target_env = "msvc"), - not(target_os = "ios"), not(thumbv6m)))] + not(target_os = "ios"), not(thumb_1)))] 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/udiv.rs b/src/int/udiv.rs index a257222..d873559 100644 --- a/src/int/udiv.rs +++ b/src/int/udiv.rs @@ -212,7 +212,7 @@ intrinsics! { #[use_c_shim_if(all(target_arch = "arm", not(target_os = "ios"), not(target_env = "msvc"), - not(thumbv6m)))] + not(thumb_1)))] /// Returns `n % d` pub extern "C" fn __umodsi3(n: u32, d: u32) -> u32 { let q = __udivsi3(n, d); @@ -222,7 +222,7 @@ intrinsics! { #[use_c_shim_if(all(target_arch = "arm", not(target_os = "ios"), not(target_env = "msvc"), - not(thumbv6m)))] + not(thumb_1)))] /// 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);