Skip to content

Commit

Permalink
Sync x86 chkstk intrinsics with LLVM
Browse files Browse the repository at this point in the history
  • Loading branch information
kleisauke committed Mar 29, 2024
1 parent 9e11560 commit d32d5ee
Show file tree
Hide file tree
Showing 3 changed files with 2 additions and 91 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ features = ["c"]
- [ ] i386/ashldi3.S
- [ ] i386/ashrdi3.S
- [x] i386/chkstk.S
- [x] i386/chkstk2.S
- [ ] i386/divdi3.S
- [ ] i386/lshrdi3.S
- [ ] i386/moddi3.S
Expand Down Expand Up @@ -192,7 +191,6 @@ features = ["c"]
- [x] umoddi3.c
- [x] umodsi3.c
- [x] x86_64/chkstk.S
- [x] x86_64/chkstk2.S

These builtins are needed to support 128-bit integers, which are in the process of being added to Rust.

Expand Down
47 changes: 2 additions & 45 deletions src/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use core::intrinsics;
// 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

intrinsics! {
#[naked]
Expand All @@ -15,50 +14,8 @@ intrinsics! {
target_env = "gnu",
not(feature = "no-asm")
))]
pub unsafe extern "C" fn ___chkstk_ms() {
core::arch::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
#[naked]
#[cfg(all(
windows,
target_env = "gnu",
not(feature = "no-asm")
))]
pub unsafe extern "C" fn __alloca() {
core::arch::asm!(
"jmp ___chkstk", // Jump to ___chkstk since fallthrough may be unreliable"
options(noreturn, att_syntax)
);
}

#[naked]
#[cfg(all(
windows,
target_env = "gnu",
not(feature = "no-asm")
))]
pub unsafe extern "C" fn ___chkstk() {
pub unsafe extern "C" fn _alloca() {
// _chkstk and _alloca are the same function
core::arch::asm!(
"push %ecx",
"cmp $0x1000,%eax",
Expand Down
44 changes: 0 additions & 44 deletions src/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use core::intrinsics;
// 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

intrinsics! {
#[naked]
Expand Down Expand Up @@ -36,49 +35,6 @@ intrinsics! {
options(noreturn, att_syntax)
);
}

#[naked]
#[cfg(all(
any(all(windows, target_env = "gnu"), target_os = "uefi"),
not(feature = "no-asm")
))]
pub unsafe extern "C" fn __alloca() {
core::arch::asm!(
"mov %rcx,%rax", // x64 _alloca is a normal function with parameter in rcx
"jmp ___chkstk", // Jump to ___chkstk since fallthrough may be unreliable"
options(noreturn, att_syntax)
);
}

#[naked]
#[cfg(all(
any(all(windows, target_env = "gnu"), target_os = "uefi"),
not(feature = "no-asm")
))]
pub unsafe extern "C" fn ___chkstk() {
core::arch::asm!(
"push %rcx",
"cmp $0x1000,%rax",
"lea 16(%rsp),%rcx", // rsp before calling this routine -> rcx
"jb 1f",
"2:",
"sub $0x1000,%rcx",
"test %rcx,(%rcx)",
"sub $0x1000,%rax",
"cmp $0x1000,%rax",
"ja 2b",
"1:",
"sub %rax,%rcx",
"test %rcx,(%rcx)",
"lea 8(%rsp),%rax", // load pointer to the return address into rax
"mov %rcx,%rsp", // install the new top of stack pointer into rsp
"mov -8(%rax),%rcx", // restore rcx
"push (%rax)", // push return address onto the stack
"sub %rsp,%rax", // restore the original value in rax
"ret",
options(noreturn, att_syntax)
);
}
}

// HACK(https://github.com/rust-lang/rust/issues/62785): x86_64-unknown-uefi needs special LLVM
Expand Down

0 comments on commit d32d5ee

Please sign in to comment.