Files
rust/library/compiler-builtins/src/x86.rs

88 lines
2.3 KiB
Rust
Raw Normal View History

2017-09-15 17:18:54 -05:00
#![allow(unused_imports)]
use core::intrinsics;
// NOTE These functions are implemented using assembly because they using a custom
// calling convention which can't be implemented using a normal Rust function
// NOTE These functions are never mangled as they are not tested against compiler-rt
// and mangling ___chkstk would break the `jmp ___chkstk` instruction in __alloca
#[cfg(all(
windows,
target_env = "gnu",
not(feature = "no-asm"),
not(feature = "mangled-names")
))]
2017-09-15 17:18:54 -05:00
#[naked]
#[no_mangle]
2017-09-15 17:18:54 -05:00
pub unsafe fn ___chkstk_ms() {
llvm_asm!("
2017-09-15 17:18:54 -05:00
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");
2017-09-15 17:18:54 -05:00
intrinsics::unreachable();
}
// FIXME: __alloca should be an alias to __chkstk
#[cfg(all(
windows,
target_env = "gnu",
not(feature = "no-asm"),
not(feature = "mangled-names")
))]
2017-09-15 17:18:54 -05:00
#[naked]
#[no_mangle]
2017-09-15 17:18:54 -05:00
pub unsafe fn __alloca() {
llvm_asm!("jmp ___chkstk // Jump to ___chkstk since fallthrough may be unreliable"
::: "memory" : "volatile");
2017-09-15 17:18:54 -05:00
intrinsics::unreachable();
}
#[cfg(all(
windows,
target_env = "gnu",
not(feature = "no-asm"),
not(feature = "mangled-names")
))]
2017-09-15 17:18:54 -05:00
#[naked]
#[no_mangle]
2017-09-15 17:18:54 -05:00
pub unsafe fn ___chkstk() {
llvm_asm!("
2017-09-15 17:18:54 -05:00
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");
2017-09-15 17:18:54 -05:00
intrinsics::unreachable();
}