Skip to content

Replace llvm_asm! with asm! #410

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

Merged
merged 1 commit into from
Apr 2, 2021
Merged
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
9 changes: 2 additions & 7 deletions examples/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#![allow(unused_features)]
#![cfg_attr(thumb, no_main)]
#![deny(dead_code)]
#![feature(llvm_asm)]
#![feature(test)]
#![feature(lang_items)]
#![feature(start)]
#![feature(allocator_api)]
Expand Down Expand Up @@ -276,14 +276,9 @@ mod intrinsics {
}

fn run() {
use core::hint::black_box as bb;
use intrinsics::*;

// A copy of "test::black_box". Used to prevent LLVM from optimizing away the intrinsics during LTO
fn bb<T>(dummy: T) -> T {
unsafe { llvm_asm!("" : : "r"(&dummy)) }
dummy
}

bb(aeabi_d2f(bb(2.)));
bb(aeabi_d2i(bb(2.)));
bb(aeabi_d2l(bb(2.)));
Expand Down
188 changes: 94 additions & 94 deletions src/arm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,135 +9,135 @@ use core::intrinsics;
#[cfg(not(any(target_os = "ios", target_env = "msvc")))]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_uidivmod() {
llvm_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();
pub unsafe extern "C" fn __aeabi_uidivmod() {
asm!(
"push {{lr}}",
"sub sp, sp, #4",
"mov r2, sp",
"bl __udivmodsi4",
"ldr r1, [sp]",
"add sp, sp, #4",
"pop {{pc}}",
options(noreturn)
);
}

#[cfg(target_os = "ios")]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_uidivmod() {
llvm_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();
pub unsafe extern "C" fn __aeabi_uidivmod() {
asm!(
"push {{lr}}",
"sub sp, sp, #4",
"mov r2, sp",
"bl ___udivmodsi4",
"ldr r1, [sp]",
"add sp, sp, #4",
"pop {{pc}}",
options(noreturn)
);
}

#[cfg(not(target_os = "ios"))]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_uldivmod() {
llvm_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();
pub unsafe extern "C" 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}}",
options(noreturn)
);
}

#[cfg(target_os = "ios")]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_uldivmod() {
llvm_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();
pub unsafe extern "C" 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}}",
options(noreturn)
);
}

#[cfg(not(target_os = "ios"))]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_idivmod() {
llvm_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();
pub unsafe extern "C" 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}}",
options(noreturn)
);
}

#[cfg(target_os = "ios")]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_idivmod() {
llvm_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();
pub unsafe extern "C" 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}}",
options(noreturn)
);
}

#[cfg(not(target_os = "ios"))]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_ldivmod() {
llvm_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();
pub unsafe extern "C" 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}}",
options(noreturn)
);
}

#[cfg(target_os = "ios")]
#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe fn __aeabi_ldivmod() {
llvm_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();
pub unsafe extern "C" 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}}",
options(noreturn)
);
}

// The following functions use weak linkage to allow users to override
Expand Down
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#![cfg_attr(feature = "compiler-builtins", compiler_builtins)]
#![cfg_attr(not(feature = "no-asm"), feature(asm))]
#![feature(abi_unadjusted)]
#![cfg_attr(not(feature = "no-asm"), feature(llvm_asm))]
#![cfg_attr(not(feature = "no-asm"), feature(global_asm))]
#![feature(cfg_target_has_atomic)]
#![feature(compiler_builtins)]
Expand Down
96 changes: 49 additions & 47 deletions src/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,27 @@ use core::intrinsics;
))]
#[naked]
#[no_mangle]
pub unsafe fn ___chkstk_ms() {
llvm_asm!("
push %ecx
push %eax
cmp $$0x1000,%eax
lea 12(%esp),%ecx
jb 1f
2:
sub $$0x1000,%ecx
test %ecx,(%ecx)
sub $$0x1000,%eax
cmp $$0x1000,%eax
ja 2b
1:
sub %eax,%ecx
test %ecx,(%ecx)
pop %eax
pop %ecx
ret" ::: "memory" : "volatile");
intrinsics::unreachable();
pub unsafe extern "C" fn ___chkstk_ms() {
asm!(
"push %ecx",
"push %eax",
"cmp $0x1000,%eax",
"lea 12(%esp),%ecx",
"jb 1f",
"2:",
"sub $0x1000,%ecx",
"test %ecx,(%ecx)",
"sub $0x1000,%eax",
"cmp $0x1000,%eax",
"ja 2b",
"1:",
"sub %eax,%ecx",
"test %ecx,(%ecx)",
"pop %eax",
"pop %ecx",
"ret",
options(noreturn, att_syntax)
);
}

// FIXME: __alloca should be an alias to __chkstk
Expand All @@ -47,10 +48,11 @@ pub unsafe fn ___chkstk_ms() {
))]
#[naked]
#[no_mangle]
pub unsafe fn __alloca() {
llvm_asm!("jmp ___chkstk // Jump to ___chkstk since fallthrough may be unreliable"
::: "memory" : "volatile");
intrinsics::unreachable();
pub unsafe extern "C" fn __alloca() {
asm!(
"jmp ___chkstk", // Jump to ___chkstk since fallthrough may be unreliable"
options(noreturn, att_syntax)
);
}

#[cfg(all(
Expand All @@ -61,27 +63,27 @@ pub unsafe fn __alloca() {
))]
#[naked]
#[no_mangle]
pub unsafe fn ___chkstk() {
llvm_asm!("
push %ecx
cmp $$0x1000,%eax
lea 8(%esp),%ecx // esp before calling this routine -> ecx
jb 1f
2:
sub $$0x1000,%ecx
test %ecx,(%ecx)
sub $$0x1000,%eax
cmp $$0x1000,%eax
ja 2b
1:
sub %eax,%ecx
test %ecx,(%ecx)

lea 4(%esp),%eax // load pointer to the return address into eax
mov %ecx,%esp // install the new top of stack pointer into esp
mov -4(%eax),%ecx // restore ecx
push (%eax) // push return address onto the stack
sub %esp,%eax // restore the original value in eax
ret" ::: "memory" : "volatile");
intrinsics::unreachable();
pub unsafe extern "C" fn ___chkstk() {
asm!(
"push %ecx",
"cmp $0x1000,%eax",
"lea 8(%esp),%ecx", // esp before calling this routine -> ecx
"jb 1f",
"2:",
"sub $0x1000,%ecx",
"test %ecx,(%ecx)",
"sub $0x1000,%eax",
"cmp $0x1000,%eax",
"ja 2b",
"1:",
"sub %eax,%ecx",
"test %ecx,(%ecx)",
"lea 4(%esp),%eax", // load pointer to the return address into eax
"mov %ecx,%esp", // install the new top of stack pointer into esp
"mov -4(%eax),%ecx", // restore ecx
"push (%eax)", // push return address onto the stack
"sub %esp,%eax", // restore the original value in eax
"ret",
options(noreturn, att_syntax)
);
}
Loading