summaryrefslogtreecommitdiffstats
path: root/vendor/compiler_builtins/src/x86_64.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/compiler_builtins/src/x86_64.rs')
-rw-r--r--vendor/compiler_builtins/src/x86_64.rs94
1 files changed, 94 insertions, 0 deletions
diff --git a/vendor/compiler_builtins/src/x86_64.rs b/vendor/compiler_builtins/src/x86_64.rs
new file mode 100644
index 000000000..393eeddd8
--- /dev/null
+++ b/vendor/compiler_builtins/src/x86_64.rs
@@ -0,0 +1,94 @@
+#![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
+
+intrinsics! {
+ #[naked]
+ #[cfg(all(
+ windows,
+ target_env = "gnu",
+ not(feature = "no-asm")
+ ))]
+ pub unsafe extern "C" fn ___chkstk_ms() {
+ core::arch::asm!(
+ "push %rcx",
+ "push %rax",
+ "cmp $0x1000,%rax",
+ "lea 24(%rsp),%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)",
+ "pop %rax",
+ "pop %rcx",
+ "ret",
+ options(noreturn, att_syntax)
+ );
+ }
+
+ #[naked]
+ #[cfg(all(
+ windows,
+ target_env = "gnu",
+ 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(
+ windows,
+ target_env = "gnu",
+ 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
+// support unless we emit the _fltused
+mod _fltused {
+ #[no_mangle]
+ #[used]
+ #[cfg(target_os = "uefi")]
+ static _fltused: i32 = 0;
+}