Skip to content

Commit 266ea07

Browse files
committed
Auto merge of #231 - paoloteti:vfp, r=alexcrichton
Collection of VFP intrinsics Nothing really exciting here, just a list of trivial VFP intrinsics. First of all set `mfloat-abi=hard` not only for thumb targets, then add support for the following intrinsics: ``` __gesf2vfp __gedf2vfp __gtsf2vfp __gtdf2vfp __ltsf2vfp __ltdf2vfp __nesf2vfp __nedf2vfp __eqsf2vfp __eqdf2vfp __extendsfdf2vfp ``` Resulting implementation is really trivial thanks to native code generated by LLVM on hard-float targets
2 parents 7c11f5c + 2467bd2 commit 266ea07

File tree

5 files changed

+150
-31
lines changed

5 files changed

+150
-31
lines changed

README.md

+16-16
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ features = ["c"]
8787
- [x] addsf3.c
8888
- [x] arm/adddf3vfp.S
8989
- [x] arm/addsf3vfp.S
90-
- [ ] arm/aeabi_dcmp.S
91-
- [ ] arm/aeabi_fcmp.S
90+
- [x] arm/aeabi_dcmp.S
91+
- [x] arm/aeabi_fcmp.S
9292
- [x] arm/aeabi_idivmod.S
9393
- [x] arm/aeabi_ldivmod.S
9494
- [x] arm/aeabi_memcpy.S
@@ -100,9 +100,9 @@ features = ["c"]
100100
- [ ] arm/divmodsi4.S (generic version is done)
101101
- [x] arm/divsf3vfp.S
102102
- [ ] arm/divsi3.S (generic version is done)
103-
- [ ] arm/eqdf2vfp.S
104-
- [ ] arm/eqsf2vfp.S
105-
- [ ] arm/extendsfdf2vfp.S
103+
- [x] arm/eqdf2vfp.S
104+
- [x] arm/eqsf2vfp.S
105+
- [x] arm/extendsfdf2vfp.S
106106
- [ ] arm/fixdfsivfp.S
107107
- [ ] arm/fixsfsivfp.S
108108
- [ ] arm/fixunsdfsivfp.S
@@ -111,22 +111,22 @@ features = ["c"]
111111
- [ ] arm/floatsisfvfp.S
112112
- [ ] arm/floatunssidfvfp.S
113113
- [ ] arm/floatunssisfvfp.S
114-
- [ ] arm/gedf2vfp.S
115-
- [ ] arm/gesf2vfp.S
116-
- [ ] arm/gtdf2vfp.S
117-
- [ ] arm/gtsf2vfp.S
114+
- [x] arm/gedf2vfp.S
115+
- [x] arm/gesf2vfp.S
116+
- [x] arm/gtdf2vfp.S
117+
- [x] arm/gtsf2vfp.S
118118
- [ ] arm/ledf2vfp.S
119119
- [ ] arm/lesf2vfp.S
120-
- [ ] arm/ltdf2vfp.S
121-
- [ ] arm/ltsf2vfp.S
120+
- [x] arm/ltdf2vfp.S
121+
- [x] arm/ltsf2vfp.S
122122
- [ ] arm/modsi3.S (generic version is done)
123123
- [x] arm/muldf3vfp.S
124124
- [x] arm/mulsf3vfp.S
125-
- [ ] arm/nedf2vfp.S
125+
- [x] arm/nedf2vfp.S
126126
- [ ] arm/negdf2vfp.S
127127
- [ ] arm/negsf2vfp.S
128-
- [ ] arm/nesf2vfp.S
129-
- [ ] arm/softfloat-alias.list
128+
- [x] arm/nesf2vfp.S
129+
- [x] arm/softfloat-alias.list
130130
- [x] arm/subdf3vfp.S
131131
- [x] arm/subsf3vfp.S
132132
- [ ] arm/truncdfsf2vfp.S
@@ -183,8 +183,8 @@ features = ["c"]
183183
- [x] mulsf3.c
184184
- [x] powidf2.c
185185
- [x] powisf2.c
186-
- [ ] subdf3.c
187-
- [ ] subsf3.c
186+
- [x] subdf3.c
187+
- [x] subsf3.c
188188
- [ ] truncdfhf2.c
189189
- [ ] truncdfsf2.c
190190
- [ ] truncsfhf2.c

build.rs

+6-15
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ mod c {
103103
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
104104
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
105105
let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap();
106-
106+
let target_arch_arm =
107+
target_arch.contains("arm") ||
108+
target_arch.contains("thumb");
107109
let cfg = &mut cc::Build::new();
108110

109111
cfg.warnings(false);
@@ -137,10 +139,10 @@ mod c {
137139
// the implementation is not valid for the arch, then gcc will error when compiling it.
138140
if llvm_target[0].starts_with("thumb") {
139141
cfg.flag("-mthumb");
142+
}
140143

141-
if llvm_target.last() == Some(&"eabihf") {
142-
cfg.flag("-mfloat-abi=hard");
143-
}
144+
if target_arch_arm && llvm_target.last() == Some(&"eabihf") {
145+
cfg.flag("-mfloat-abi=hard");
144146
}
145147

146148
if llvm_target[0] == "thumbv6m" {
@@ -374,9 +376,6 @@ mod c {
374376
if !llvm_target[0].starts_with("thumbv7em") {
375377
sources.extend(
376378
&[
377-
"arm/eqdf2vfp.S",
378-
"arm/eqsf2vfp.S",
379-
"arm/extendsfdf2vfp.S",
380379
"arm/fixdfsivfp.S",
381380
"arm/fixsfsivfp.S",
382381
"arm/fixunsdfsivfp.S",
@@ -385,16 +384,8 @@ mod c {
385384
"arm/floatsisfvfp.S",
386385
"arm/floatunssidfvfp.S",
387386
"arm/floatunssisfvfp.S",
388-
"arm/gedf2vfp.S",
389-
"arm/gesf2vfp.S",
390-
"arm/gtdf2vfp.S",
391-
"arm/gtsf2vfp.S",
392387
"arm/ledf2vfp.S",
393388
"arm/lesf2vfp.S",
394-
"arm/ltdf2vfp.S",
395-
"arm/ltsf2vfp.S",
396-
"arm/nedf2vfp.S",
397-
"arm/nesf2vfp.S",
398389
"arm/restore_vfp_d8_d15_regs.S",
399390
"arm/save_vfp_d8_d15_regs.S",
400391
],

src/float/cmp.rs

+43
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,47 @@ intrinsics! {
212212
pub extern "aapcs" fn __aeabi_dcmpgt(a: f64, b: f64) -> i32 {
213213
(__gtdf2(a, b) > 0) as i32
214214
}
215+
216+
// On hard-float targets LLVM will use native instructions
217+
// for all VFP intrinsics below
218+
219+
pub extern "C" fn __gesf2vfp(a: f32, b: f32) -> i32 {
220+
(a >= b) as i32
221+
}
222+
223+
pub extern "C" fn __gedf2vfp(a: f64, b: f64) -> i32 {
224+
(a >= b) as i32
225+
}
226+
227+
pub extern "C" fn __gtsf2vfp(a: f32, b: f32) -> i32 {
228+
(a > b) as i32
229+
}
230+
231+
pub extern "C" fn __gtdf2vfp(a: f64, b: f64) -> i32 {
232+
(a > b) as i32
233+
}
234+
235+
pub extern "C" fn __ltsf2vfp(a: f32, b: f32) -> i32 {
236+
(a < b) as i32
237+
}
238+
239+
pub extern "C" fn __ltdf2vfp(a: f64, b: f64) -> i32 {
240+
(a < b) as i32
241+
}
242+
243+
pub extern "C" fn __nesf2vfp(a: f32, b: f32) -> i32 {
244+
(a != b) as i32
245+
}
246+
247+
pub extern "C" fn __nedf2vfp(a: f64, b: f64) -> i32 {
248+
(a != b) as i32
249+
}
250+
251+
pub extern "C" fn __eqsf2vfp(a: f32, b: f32) -> i32 {
252+
(a == b) as i32
253+
}
254+
255+
pub extern "C" fn __eqdf2vfp(a: f64, b: f64) -> i32 {
256+
(a == b) as i32
257+
}
215258
}

src/float/extend.rs

+5
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,9 @@ intrinsics! {
7474
pub extern "C" fn __extendsfdf2(a: f32) -> f64 {
7575
extend(a)
7676
}
77+
78+
#[cfg(target_arch = "arm")]
79+
pub extern "C" fn __extendsfdf2vfp(a: f32) -> f64 {
80+
a as f64 // LLVM generate 'fcvtds'
81+
}
7782
}

testcrate/build.rs

+80
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,77 @@ fn main() {
233233
Some(c)
234234
},
235235
"compiler_builtins::float::cmp::__aeabi_dcmpgt(a, b)");
236+
237+
gen(|(a, b): (LargeF32, LargeF32)| {
238+
if a.0.is_nan() || b.0.is_nan() {
239+
return None;
240+
}
241+
Some((a.0 >= b.0) as i32)
242+
},
243+
"compiler_builtins::float::cmp::__gesf2vfp(a, b)");
244+
gen(|(a, b): (MyF64, MyF64)| {
245+
if a.0.is_nan() || b.0.is_nan() {
246+
return None;
247+
}
248+
Some((a.0 >= b.0) as i32)
249+
},
250+
"compiler_builtins::float::cmp::__gedf2vfp(a, b)");
251+
gen(|(a, b): (LargeF32, LargeF32)| {
252+
if a.0.is_nan() || b.0.is_nan() {
253+
return None;
254+
}
255+
Some((a.0 > b.0) as i32)
256+
},
257+
"compiler_builtins::float::cmp::__gtsf2vfp(a, b)");
258+
gen(|(a, b): (MyF64, MyF64)| {
259+
if a.0.is_nan() || b.0.is_nan() {
260+
return None;
261+
}
262+
Some((a.0 > b.0) as i32)
263+
},
264+
"compiler_builtins::float::cmp::__gtdf2vfp(a, b)");
265+
gen(|(a, b): (LargeF32, LargeF32)| {
266+
if a.0.is_nan() || b.0.is_nan() {
267+
return None;
268+
}
269+
Some((a.0 < b.0) as i32)
270+
},
271+
"compiler_builtins::float::cmp::__ltsf2vfp(a, b)");
272+
gen(|(a, b): (MyF64, MyF64)| {
273+
if a.0.is_nan() || b.0.is_nan() {
274+
return None;
275+
}
276+
Some((a.0 < b.0) as i32)
277+
},
278+
"compiler_builtins::float::cmp::__ltdf2vfp(a, b)");
279+
gen(|(a, b): (LargeF32, LargeF32)| {
280+
if a.0.is_nan() || b.0.is_nan() {
281+
return None;
282+
}
283+
Some((a.0 != b.0) as i32)
284+
},
285+
"compiler_builtins::float::cmp::__nesf2vfp(a, b)");
286+
gen(|(a, b): (MyF64, MyF64)| {
287+
if a.0.is_nan() || b.0.is_nan() {
288+
return None;
289+
}
290+
Some((a.0 != b.0) as i32)
291+
},
292+
"compiler_builtins::float::cmp::__nedf2vfp(a, b)");
293+
gen(|(a, b): (LargeF32, LargeF32)| {
294+
if a.0.is_nan() || b.0.is_nan() {
295+
return None;
296+
}
297+
Some((a.0 == b.0) as i32)
298+
},
299+
"compiler_builtins::float::cmp::__eqsf2vfp(a, b)");
300+
gen(|(a, b): (MyF64, MyF64)| {
301+
if a.0.is_nan() || b.0.is_nan() {
302+
return None;
303+
}
304+
Some((a.0 == b.0) as i32)
305+
},
306+
"compiler_builtins::float::cmp::__eqdf2vfp(a, b)");
236307
}
237308

238309
// float/extend.rs
@@ -243,6 +314,15 @@ fn main() {
243314
Some(f64(a.0))
244315
},
245316
"compiler_builtins::float::extend::__extendsfdf2(a)");
317+
if target_arch_arm {
318+
gen(|a: LargeF32| {
319+
if a.0.is_nan() {
320+
return None;
321+
}
322+
Some(f64(a.0))
323+
},
324+
"compiler_builtins::float::extend::__extendsfdf2vfp(a)");
325+
}
246326

247327
// float/conv.rs
248328
gen(|a: MyF64| i64(a.0).ok(),

0 commit comments

Comments
 (0)