Skip to content

Commit 82bf52c

Browse files
author
Jorge Aparicio
committed
a bunch of thumbv6m related fixes
Where the optimized compiler-rt assembly implementation doesn't compile, use our Rust implementation. If that's not available, use the compiler-rt C implementation. Some operations like `f64 < f64` are not possible on the thumbv6m target because there is no available implementation (\*) so omit testing for those in intrinsics.rs until we have a Rust implementation in place. (\*) In all cases, there *is* an assembly implementation in compiler-rt but that implementation doesn't compile for the thumbv6m because that target doesn't support the full THUMBv2 instruction set.
1 parent b08b42d commit 82bf52c

File tree

5 files changed

+78
-6
lines changed

5 files changed

+78
-6
lines changed

build.rs

+9
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,9 @@ fn main() {
395395
"aeabi_memset", "aeabi_uldivmod", "clzdi2", "clzsi2", "comparesf2",
396396
"divmodsi4", "divsi3", "modsi3", "switch16", "switch32", "switch8",
397397
"switchu8", "udivmodsi4", "udivsi3", "umodsi3"]);
398+
399+
// But use some generic implementations where possible
400+
sources.extend(&["clzdi2.c", "clzsi2.c"])
398401
}
399402

400403
if llvm_target[0] == "thumbv7m" || llvm_target[0] == "thumbv7em" {
@@ -417,4 +420,10 @@ fn main() {
417420
if llvm_target[0].starts_with("thumb") {
418421
println!("cargo:rustc-cfg=thumb")
419422
}
423+
424+
// compiler-rt `cfg`s away some intrinsics for thumbv6m because that target doesn't have full
425+
// THUMBv2 support. We have to cfg our code accordingly.
426+
if llvm_target[0] == "thumbv6m" {
427+
println!("cargo:rustc-cfg=thumbv6m")
428+
}
420429
}

src/arm.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ pub extern "C" fn __aeabi_fadd(a: f32, b: f32) -> f32 {
6868
::float::add::__addsf3(a, b)
6969
}
7070

71-
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))]
71+
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
7272
#[cfg_attr(not(test), no_mangle)]
7373
pub extern "C" fn __aeabi_idiv(a: i32, b: i32) -> i32 {
7474
::int::sdiv::__divsi3(a, b)
@@ -94,7 +94,7 @@ pub extern "C" fn __aeabi_lmul(a: u64, b: u64) -> u64 {
9494
::int::mul::__muldi3(a, b)
9595
}
9696

97-
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))]
97+
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
9898
#[cfg_attr(not(test), no_mangle)]
9999
pub extern "C" fn __aeabi_uidiv(a: u32, b: u32) -> u32 {
100100
::int::udiv::__udivsi3(a, b)

src/bin/intrinsics.rs

+63
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
extern crate libc;
1717
extern crate rustc_builtins;
1818

19+
// NOTE cfg(not(thumbv6m)) means that the operation is not supported on ARMv6-M at all. Not even
20+
// compiler-rt provides a C/assembly implementation.
21+
1922
// Every function in this module maps will be lowered to an intrinsic by LLVM, if the platform
2023
// doesn't have native support for the operation used in the function. ARM has a naming convention
2124
// convention for its intrinsics that's different from other architectures; that's why some function
@@ -36,40 +39,70 @@ mod intrinsics {
3639
}
3740

3841
// fixdfdi
42+
#[cfg(not(thumbv6m))]
3943
pub fn aeabi_d2l(x: f64) -> i64 {
4044
x as i64
4145
}
4246

47+
#[cfg(thumbv6m)]
48+
pub fn aeabi_d2l(_: f64) -> i64 {
49+
0
50+
}
51+
4352
// fixunsdfsi
4453
pub fn aeabi_d2uiz(x: f64) -> u32 {
4554
x as u32
4655
}
4756

4857
// fixunsdfdi
58+
#[cfg(not(thumbv6m))]
4959
pub fn aeabi_d2ulz(x: f64) -> u64 {
5060
x as u64
5161
}
5262

63+
#[cfg(thumbv6m)]
64+
pub fn aeabi_d2ulz(_: f64) -> u64 {
65+
0
66+
}
67+
5368
// adddf3
5469
pub fn aeabi_dadd(a: f64, b: f64) -> f64 {
5570
a + b
5671
}
5772

5873
// eqdf2
74+
#[cfg(not(thumbv6m))]
5975
pub fn aeabi_dcmpeq(a: f64, b: f64) -> bool {
6076
a == b
6177
}
6278

79+
#[cfg(thumbv6m)]
80+
pub fn aeabi_dcmpeq(_: f64, _: f64) -> bool {
81+
true
82+
}
83+
6384
// gtdf2
85+
#[cfg(not(thumbv6m))]
6486
pub fn aeabi_dcmpgt(a: f64, b: f64) -> bool {
6587
a > b
6688
}
6789

90+
#[cfg(thumbv6m)]
91+
pub fn aeabi_dcmpgt(_: f64, _: f64) -> bool {
92+
true
93+
}
94+
6895
// ltdf2
96+
#[cfg(not(thumbv6m))]
6997
pub fn aeabi_dcmplt(a: f64, b: f64) -> bool {
7098
a < b
7199
}
72100

101+
#[cfg(thumbv6m)]
102+
pub fn aeabi_dcmplt(_: f64, _: f64) -> bool {
103+
true
104+
}
105+
73106
// divdf3
74107
pub fn aeabi_ddiv(a: f64, b: f64) -> f64 {
75108
a / b
@@ -96,40 +129,70 @@ mod intrinsics {
96129
}
97130

98131
// fixsfdi
132+
#[cfg(not(thumbv6m))]
99133
pub fn aeabi_f2lz(x: f32) -> i64 {
100134
x as i64
101135
}
102136

137+
#[cfg(thumbv6m)]
138+
pub fn aeabi_f2lz(_: f32) -> i64 {
139+
0
140+
}
141+
103142
// fixunssfsi
104143
pub fn aeabi_f2uiz(x: f32) -> u32 {
105144
x as u32
106145
}
107146

108147
// fixunssfdi
148+
#[cfg(not(thumbv6m))]
109149
pub fn aeabi_f2ulz(x: f32) -> u64 {
110150
x as u64
111151
}
112152

153+
#[cfg(thumbv6m)]
154+
pub fn aeabi_f2ulz(_: f32) -> u64 {
155+
0
156+
}
157+
113158
// addsf3
114159
pub fn aeabi_fadd(a: f32, b: f32) -> f32 {
115160
a + b
116161
}
117162

118163
// eqsf2
164+
#[cfg(not(thumbv6m))]
119165
pub fn aeabi_fcmpeq(a: f32, b: f32) -> bool {
120166
a == b
121167
}
122168

169+
#[cfg(thumbv6m)]
170+
pub fn aeabi_fcmpeq(_: f32, _: f32) -> bool {
171+
true
172+
}
173+
123174
// gtsf2
175+
#[cfg(not(thumbv6m))]
124176
pub fn aeabi_fcmpgt(a: f32, b: f32) -> bool {
125177
a > b
126178
}
127179

180+
#[cfg(thumbv6m)]
181+
pub fn aeabi_fcmpgt(_: f32, _: f32) -> bool {
182+
true
183+
}
184+
128185
// ltsf2
186+
#[cfg(not(thumbv6m))]
129187
pub fn aeabi_fcmplt(a: f32, b: f32) -> bool {
130188
a < b
131189
}
132190

191+
#[cfg(thumbv6m)]
192+
pub fn aeabi_fcmplt(_: f32, _: f32) -> bool {
193+
true
194+
}
195+
133196
// divsf3
134197
pub fn aeabi_fdiv(a: f32, b: f32) -> f32 {
135198
a / b

src/int/sdiv.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ macro_rules! divmod {
4848
}
4949
}
5050

51-
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))]
51+
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
5252
div!(__divsi3: i32, u32);
5353

5454
#[cfg(not(all(feature = "c", target_arch = "x86")))]

src/int/udiv.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use core::mem;
22
use int::{Int, LargeInt};
33

44
/// Returns `n / d`
5-
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))]
5+
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
66
#[cfg_attr(not(test), no_mangle)]
77
pub extern "C" fn __udivsi3(n: u32, d: u32) -> u32 {
88
// Special cases
@@ -65,15 +65,15 @@ pub extern "C" fn __umodsi3(n: u32, d: u32) -> u32 {
6565
}
6666

6767
/// Returns `n / d` and sets `*rem = n % d`
68-
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))]
68+
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
6969
#[cfg_attr(not(test), no_mangle)]
7070
pub extern "C" fn __udivmodsi4(n: u32, d: u32, rem: Option<&mut u32>) -> u32 {
7171
#[cfg(all(feature = "c", target_arch = "arm", not(target_os = "ios")))]
7272
extern {
7373
fn __udivsi3(n: u32, d: u32) -> u32;
7474
}
7575

76-
let q = __udivsi3(n, d);
76+
let q = unsafe { __udivsi3(n, d) };
7777
if let Some(rem) = rem {
7878
*rem = n - (q * d);
7979
}

0 commit comments

Comments
 (0)