Skip to content

Implement {add,sub,mul,neg,div} vfp #153

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

Closed
wants to merge 2 commits into from
Closed
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
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ features = ["c"]

- [x] adddf3.c
- [x] addsf3.c
- [ ] arm/adddf3vfp.S
- [ ] arm/addsf3vfp.S
- [x] arm/adddf3vfp.S
- [x] arm/addsf3vfp.S
- [ ] arm/aeabi_dcmp.S
- [ ] arm/aeabi_fcmp.S
- [x] arm/aeabi_idivmod.S
Expand All @@ -92,9 +92,9 @@ features = ["c"]
- [x] arm/aeabi_memset.S
- [x] arm/aeabi_uidivmod.S
- [x] arm/aeabi_uldivmod.S
- [ ] arm/divdf3vfp.S
- [x] arm/divdf3vfp.S
- [ ] arm/divmodsi4.S (generic version is done)
- [ ] arm/divsf3vfp.S
- [x] arm/divsf3vfp.S
- [ ] arm/divsi3.S (generic version is done)
- [ ] arm/eqdf2vfp.S
- [ ] arm/eqsf2vfp.S
Expand All @@ -116,15 +116,15 @@ features = ["c"]
- [ ] arm/ltdf2vfp.S
- [ ] arm/ltsf2vfp.S
- [ ] arm/modsi3.S (generic version is done)
- [ ] arm/muldf3vfp.S
- [ ] arm/mulsf3vfp.S
- [x] arm/muldf3vfp.S
- [x] arm/mulsf3vfp.S
- [ ] arm/nedf2vfp.S
- [ ] arm/negdf2vfp.S
- [ ] arm/negsf2vfp.S
- [x] arm/negdf2vfp.S
- [x] arm/negsf2vfp.S
- [ ] arm/nesf2vfp.S
- [ ] arm/softfloat-alias.list
- [ ] arm/subdf3vfp.S
- [ ] arm/subsf3vfp.S
- [x] arm/subdf3vfp.S
- [x] arm/subsf3vfp.S
- [ ] arm/truncdfsf2vfp.S
- [ ] arm/udivmodsi4.S (generic version is done)
- [ ] arm/udivsi3.S (generic version is done)
Expand Down
21 changes: 8 additions & 13 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,11 +314,7 @@ fn main() {

if llvm_target.last().unwrap().ends_with("eabihf") {
if !llvm_target[0].starts_with("thumbv7em") {
sources.extend(&["arm/adddf3vfp.S",
"arm/addsf3vfp.S",
"arm/divdf3vfp.S",
"arm/divsf3vfp.S",
"arm/eqdf2vfp.S",
sources.extend(&["arm/eqdf2vfp.S",
"arm/eqsf2vfp.S",
"arm/extendsfdf2vfp.S",
"arm/fixdfsivfp.S",
Expand All @@ -337,18 +333,11 @@ fn main() {
"arm/lesf2vfp.S",
"arm/ltdf2vfp.S",
"arm/ltsf2vfp.S",
"arm/muldf3vfp.S",
"arm/mulsf3vfp.S",
"arm/nedf2vfp.S",
"arm/nesf2vfp.S",
"arm/restore_vfp_d8_d15_regs.S",
"arm/save_vfp_d8_d15_regs.S",
"arm/subdf3vfp.S",
"arm/subsf3vfp.S"]);
"arm/save_vfp_d8_d15_regs.S"]);
}

sources.extend(&["arm/negdf2vfp.S", "arm/negsf2vfp.S"]);

}

if target_arch == "aarch64" {
Expand Down Expand Up @@ -433,4 +422,10 @@ fn main() {
if llvm_target[0] == "thumbv6m" {
println!("cargo:rustc-cfg=thumbv6m")
}

// Needed for ARM VFP assembly functions
if llvm_target.last().unwrap().ends_with("hf") ||
llvm_target[0] == "aarch64" {
println!("cargo:rustc-cfg=armhf")
}
}
136 changes: 136 additions & 0 deletions src/arm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,142 @@ use core::intrinsics;
#[cfg(feature = "mem")]
use mem::{memcpy, memmove, memset};

// Thumb1 code can't encode hardware float operations, so some targets
// need functions that wrap the appropriate ARM instructions.
#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn __adddf3vfp() {
#[cfg(armhf)]
asm!("vadd.f64 d0, d0, d1");
#[cfg(not(armhf))]
asm!("vmov d6, r0, r1
vmov d7, r2, r3
vadd.f64 d6, d6, d7
vmov r0, r1, d6");
asm!("bx lr");
intrinsics::unreachable();
}

#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn __addsf3vfp() {
#[cfg(armhf)]
asm!("vadd.f32 s0, s0, s1");
#[cfg(not(armhf))]
asm!("vmov s14, r0
vmov s15, r1
vadd.f32 s14, s14, s15
vmov r0, s14");
asm!("bx lr");
intrinsics::unreachable();
}

#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn __divdf3vfp() {
#[cfg(armhf)]
asm!("vdiv.f64 d0, d0, d1");
#[cfg(not(armhf))]
asm!("vmov d6, r0, r1
vmov d7, r2, r3
vdiv.f64 d5, d6, d7
vmov r0, r1, d5");
asm!("bx lr");
intrinsics::unreachable();
}

#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn __divsf3vfp() {
#[cfg(armhf)]
asm!("vdiv.f32 s0, s0, s1");
#[cfg(not(armhf))]
asm!("vmov s14, r0
vmov s15, r1
vdiv.f32 s13, s14, s15
vmov r0, s13");
asm!("bx lr");
intrinsics::unreachable();
}

#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn __muldf3vfp() {
#[cfg(armhf)]
asm!("vmul.f64 d0, d0, d1");
#[cfg(not(armhf))]
asm!("vmov d6, r0, r1
vmov d7, r2, r3
vmul.f64 d6, d6, d7
vmov r0, r1, d6");
asm!("bx lr");
intrinsics::unreachable();
}

#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn __mulsf3vfp() {
#[cfg(armhf)]
asm!("vmul.f32 s0, s0, s1");
#[cfg(not(armhf))]
asm!("vmov s14, r0
vmov s15, r1
vmul.f32 s13, s14, s15
vmov r0, s13");
asm!("bx lr");
intrinsics::unreachable();
}

#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn __negdf2vfp() {
#[cfg(armhf)]
asm!("vneg.f64 d0, d0");
#[cfg(not(armhf))]
asm!("eor r1, r1, #-2147483648");
asm!("bx lr");
intrinsics::unreachable();
}

#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn __negsf2vfp() {
#[cfg(armhf)]
asm!("vneg.f32 s0, s0");
#[cfg(not(armhf))]
asm!("eor r0, r0, #-2147483648");
asm!("bx lr");
intrinsics::unreachable();
}

#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn __subdf3vfp() {
#[cfg(armhf)]
asm!("vsub.f64 d0, d0, d1");
#[cfg(not(armhf))]
asm!("vmov d6, r0, r1
vmov d7, r2, r3
vsub.f64 d6, d6, d7
vmov r0, r1, d6");
asm!("bx lr");
intrinsics::unreachable();
}

#[naked]
#[cfg_attr(not(test), no_mangle)]
pub unsafe fn __subsf3vfp() {
#[cfg(armhf)]
asm!("vsub.f32 s0, s0, s1");
#[cfg(not(armhf))]
asm!("vmov s14, r0
vmov s15, r1
vsub.f32 s14, s14, s15
vmov r0, s14");
asm!("bx lr");
intrinsics::unreachable();
}

// NOTE This function and the ones below are implemented using assembly because they using a custom
// calling convention which can't be implemented using a normal Rust function
#[naked]
Expand Down