Skip to content

Fix compilation errors for Armv8-M Baseline and Mainline with FPU #276

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 26 additions & 13 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,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.
Expand Down Expand Up @@ -359,24 +360,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",
]
);

}

Expand Down Expand Up @@ -407,7 +420,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",
Expand Down
63 changes: 0 additions & 63 deletions examples/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions src/int/sdiv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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))
}
Expand Down
4 changes: 2 additions & 2 deletions src/int/udiv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down