Skip to content

Commit

Permalink
Merge pull request #238 from TimNN/fix-arm
Browse files Browse the repository at this point in the history
Fix incorrect names used / generated on ARM
  • Loading branch information
alexcrichton committed Mar 27, 2018
2 parents 263a703 + 5be5465 commit 2a2f6d9
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
67 changes: 66 additions & 1 deletion src/arm.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use core::intrinsics;

// 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
// calling convention which can't be implemented using a normal Rust function.
// NOTE The only difference between the iOS and non-iOS versions of those functions is that the iOS
// versions use 3 leading underscores in the names of called functions instead of 2.
#[cfg(not(target_os = "ios"))]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_uidivmod() {
Expand All @@ -15,6 +18,21 @@ pub unsafe fn __aeabi_uidivmod() {
intrinsics::unreachable();
}

#[cfg(target_os = "ios")]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_uidivmod() {
asm!("push {lr}
sub sp, sp, #4
mov r2, sp
bl ___udivmodsi4
ldr r1, [sp]
add sp, sp, #4
pop {pc}" ::: "memory" : "volatile");
intrinsics::unreachable();
}

#[cfg(not(target_os = "ios"))]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_uldivmod() {
Expand All @@ -30,6 +48,23 @@ pub unsafe fn __aeabi_uldivmod() {
intrinsics::unreachable();
}

#[cfg(target_os = "ios")]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_uldivmod() {
asm!("push {r4, lr}
sub sp, sp, #16
add r4, sp, #8
str r4, [sp]
bl ___udivmoddi4
ldr r2, [sp, #8]
ldr r3, [sp, #12]
add sp, sp, #16
pop {r4, pc}" ::: "memory" : "volatile");
intrinsics::unreachable();
}

#[cfg(not(target_os = "ios"))]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_idivmod() {
Expand All @@ -42,6 +77,20 @@ pub unsafe fn __aeabi_idivmod() {
intrinsics::unreachable();
}

#[cfg(target_os = "ios")]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_idivmod() {
asm!("push {r0, r1, r4, lr}
bl ___aeabi_idiv
pop {r1, r2}
muls r2, r2, r0
subs r1, r1, r2
pop {r4, pc}" ::: "memory" : "volatile");
intrinsics::unreachable();
}

#[cfg(not(target_os = "ios"))]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_ldivmod() {
Expand All @@ -57,6 +106,22 @@ pub unsafe fn __aeabi_ldivmod() {
intrinsics::unreachable();
}

#[cfg(target_os = "ios")]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_ldivmod() {
asm!("push {r4, lr}
sub sp, sp, #16
add r4, sp, #8
str r4, [sp]
bl ___divmoddi4
ldr r2, [sp, #8]
ldr r3, [sp, #12]
add sp, sp, #16
pop {r4, pc}" ::: "memory" : "volatile");
intrinsics::unreachable();
}

// FIXME: The `*4` and `*8` variants should be defined as aliases.

#[cfg(not(target_os = "ios"))]
Expand Down
1 change: 1 addition & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ macro_rules! intrinsics {
$($rest:tt)*
) => (
#[cfg(target_arch = "arm")]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub extern $abi fn $name( $($argname: $ty),* ) -> $ret {
$($body)*
}
Expand Down

0 comments on commit 2a2f6d9

Please sign in to comment.