From e7bf03019c403a54ecf994b67c67dd01e734a604 Mon Sep 17 00:00:00 2001 From: Paolo Teti Date: Sun, 11 Feb 2018 23:46:56 +0100 Subject: [PATCH] Collection of VFP intrinsics Nothing really exciting here. LLVM on hard-float target use native instructions for all listed VFP intrinsics and so resulting implementation is really trivial. Implemented intrinsics: __gesf2vfp __gedf2vfp __gtsf2vfp __gtdf2vfp __ltsf2vfp __ltdf2vfp __nesf2vfp __nedf2vfp __eqsf2vfp __eqdf2vfp __extendsfdf2vfp --- README.md | 24 +++++++------- build.rs | 11 ------- src/float/cmp.rs | 43 ++++++++++++++++++++++++ src/float/extend.rs | 5 +++ testcrate/build.rs | 80 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 140 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 30abd92..8d59594 100644 --- a/README.md +++ b/README.md @@ -100,9 +100,9 @@ features = ["c"] - [ ] arm/divmodsi4.S (generic version is done) - [x] arm/divsf3vfp.S - [ ] arm/divsi3.S (generic version is done) -- [ ] arm/eqdf2vfp.S -- [ ] arm/eqsf2vfp.S -- [ ] arm/extendsfdf2vfp.S +- [x] arm/eqdf2vfp.S +- [x] arm/eqsf2vfp.S +- [x] arm/extendsfdf2vfp.S - [ ] arm/fixdfsivfp.S - [ ] arm/fixsfsivfp.S - [ ] arm/fixunsdfsivfp.S @@ -111,22 +111,22 @@ features = ["c"] - [ ] arm/floatsisfvfp.S - [ ] arm/floatunssidfvfp.S - [ ] arm/floatunssisfvfp.S -- [ ] arm/gedf2vfp.S -- [ ] arm/gesf2vfp.S -- [ ] arm/gtdf2vfp.S -- [ ] arm/gtsf2vfp.S +- [x] arm/gedf2vfp.S +- [x] arm/gesf2vfp.S +- [x] arm/gtdf2vfp.S +- [x] arm/gtsf2vfp.S - [ ] arm/ledf2vfp.S - [ ] arm/lesf2vfp.S -- [ ] arm/ltdf2vfp.S -- [ ] arm/ltsf2vfp.S +- [x] arm/ltdf2vfp.S +- [x] arm/ltsf2vfp.S - [ ] arm/modsi3.S (generic version is done) - [x] arm/muldf3vfp.S - [x] arm/mulsf3vfp.S -- [ ] arm/nedf2vfp.S +- [x] arm/nedf2vfp.S - [ ] arm/negdf2vfp.S - [ ] arm/negsf2vfp.S -- [ ] arm/nesf2vfp.S -- [ ] arm/softfloat-alias.list +- [x] arm/nesf2vfp.S +- [x] arm/softfloat-alias.list - [x] arm/subdf3vfp.S - [x] arm/subsf3vfp.S - [ ] arm/truncdfsf2vfp.S diff --git a/build.rs b/build.rs index 6a05727..594afbd 100644 --- a/build.rs +++ b/build.rs @@ -376,9 +376,6 @@ mod c { if !llvm_target[0].starts_with("thumbv7em") { sources.extend( &[ - "arm/eqdf2vfp.S", - "arm/eqsf2vfp.S", - "arm/extendsfdf2vfp.S", "arm/fixdfsivfp.S", "arm/fixsfsivfp.S", "arm/fixunsdfsivfp.S", @@ -387,16 +384,8 @@ mod c { "arm/floatsisfvfp.S", "arm/floatunssidfvfp.S", "arm/floatunssisfvfp.S", - "arm/gedf2vfp.S", - "arm/gesf2vfp.S", - "arm/gtdf2vfp.S", - "arm/gtsf2vfp.S", "arm/ledf2vfp.S", "arm/lesf2vfp.S", - "arm/ltdf2vfp.S", - "arm/ltsf2vfp.S", - "arm/nedf2vfp.S", - "arm/nesf2vfp.S", "arm/restore_vfp_d8_d15_regs.S", "arm/save_vfp_d8_d15_regs.S", ], diff --git a/src/float/cmp.rs b/src/float/cmp.rs index 4986d05..16b059e 100644 --- a/src/float/cmp.rs +++ b/src/float/cmp.rs @@ -212,4 +212,47 @@ intrinsics! { pub extern "aapcs" fn __aeabi_dcmpgt(a: f64, b: f64) -> i32 { (__gtdf2(a, b) > 0) as i32 } + + // On hard-float targets LLVM will use native instructions + // for all VFP intrinsics below + + pub extern "C" fn __gesf2vfp(a: f32, b: f32) -> i32 { + (a >= b) as i32 + } + + pub extern "C" fn __gedf2vfp(a: f64, b: f64) -> i32 { + (a >= b) as i32 + } + + pub extern "C" fn __gtsf2vfp(a: f32, b: f32) -> i32 { + (a > b) as i32 + } + + pub extern "C" fn __gtdf2vfp(a: f64, b: f64) -> i32 { + (a > b) as i32 + } + + pub extern "C" fn __ltsf2vfp(a: f32, b: f32) -> i32 { + (a < b) as i32 + } + + pub extern "C" fn __ltdf2vfp(a: f64, b: f64) -> i32 { + (a < b) as i32 + } + + pub extern "C" fn __nesf2vfp(a: f32, b: f32) -> i32 { + (a != b) as i32 + } + + pub extern "C" fn __nedf2vfp(a: f64, b: f64) -> i32 { + (a != b) as i32 + } + + pub extern "C" fn __eqsf2vfp(a: f32, b: f32) -> i32 { + (a == b) as i32 + } + + pub extern "C" fn __eqdf2vfp(a: f64, b: f64) -> i32 { + (a == b) as i32 + } } diff --git a/src/float/extend.rs b/src/float/extend.rs index a71b7a1..0ca9cf5 100644 --- a/src/float/extend.rs +++ b/src/float/extend.rs @@ -74,4 +74,9 @@ intrinsics! { pub extern "C" fn __extendsfdf2(a: f32) -> f64 { extend(a) } + + #[cfg(target_arch = "arm")] + pub extern "C" fn __extendsfdf2vfp(a: f32) -> f64 { + a as f64 // LLVM generate 'fcvtds' + } } \ No newline at end of file diff --git a/testcrate/build.rs b/testcrate/build.rs index 40cc1db..d3850cc 100644 --- a/testcrate/build.rs +++ b/testcrate/build.rs @@ -233,6 +233,77 @@ fn main() { Some(c) }, "compiler_builtins::float::cmp::__aeabi_dcmpgt(a, b)"); + + gen(|(a, b): (LargeF32, LargeF32)| { + if a.0.is_nan() || b.0.is_nan() { + return None; + } + Some((a.0 >= b.0) as i32) + }, + "compiler_builtins::float::cmp::__gesf2vfp(a, b)"); + gen(|(a, b): (MyF64, MyF64)| { + if a.0.is_nan() || b.0.is_nan() { + return None; + } + Some((a.0 >= b.0) as i32) + }, + "compiler_builtins::float::cmp::__gedf2vfp(a, b)"); + gen(|(a, b): (LargeF32, LargeF32)| { + if a.0.is_nan() || b.0.is_nan() { + return None; + } + Some((a.0 > b.0) as i32) + }, + "compiler_builtins::float::cmp::__gtsf2vfp(a, b)"); + gen(|(a, b): (MyF64, MyF64)| { + if a.0.is_nan() || b.0.is_nan() { + return None; + } + Some((a.0 > b.0) as i32) + }, + "compiler_builtins::float::cmp::__gtdf2vfp(a, b)"); + gen(|(a, b): (LargeF32, LargeF32)| { + if a.0.is_nan() || b.0.is_nan() { + return None; + } + Some((a.0 < b.0) as i32) + }, + "compiler_builtins::float::cmp::__ltsf2vfp(a, b)"); + gen(|(a, b): (MyF64, MyF64)| { + if a.0.is_nan() || b.0.is_nan() { + return None; + } + Some((a.0 < b.0) as i32) + }, + "compiler_builtins::float::cmp::__ltdf2vfp(a, b)"); + gen(|(a, b): (LargeF32, LargeF32)| { + if a.0.is_nan() || b.0.is_nan() { + return None; + } + Some((a.0 != b.0) as i32) + }, + "compiler_builtins::float::cmp::__nesf2vfp(a, b)"); + gen(|(a, b): (MyF64, MyF64)| { + if a.0.is_nan() || b.0.is_nan() { + return None; + } + Some((a.0 != b.0) as i32) + }, + "compiler_builtins::float::cmp::__nedf2vfp(a, b)"); + gen(|(a, b): (LargeF32, LargeF32)| { + if a.0.is_nan() || b.0.is_nan() { + return None; + } + Some((a.0 == b.0) as i32) + }, + "compiler_builtins::float::cmp::__eqsf2vfp(a, b)"); + gen(|(a, b): (MyF64, MyF64)| { + if a.0.is_nan() || b.0.is_nan() { + return None; + } + Some((a.0 == b.0) as i32) + }, + "compiler_builtins::float::cmp::__eqdf2vfp(a, b)"); } // float/extend.rs @@ -243,6 +314,15 @@ fn main() { Some(f64(a.0)) }, "compiler_builtins::float::extend::__extendsfdf2(a)"); + if target_arch_arm { + gen(|a: LargeF32| { + if a.0.is_nan() { + return None; + } + Some(f64(a.0)) + }, + "compiler_builtins::float::extend::__extendsfdf2vfp(a)"); + } // float/conv.rs gen(|a: MyF64| i64(a.0).ok(),