]>
Commit | Line | Data |
---|---|---|
041b39d2 XL |
1 | #![allow(unused_imports)] |
2 | ||
3 | use core::intrinsics; | |
4 | ||
5 | // NOTE These functions are implemented using assembly because they using a custom | |
6 | // calling convention which can't be implemented using a normal Rust function | |
7 | ||
8 | // NOTE These functions are never mangled as they are not tested against compiler-rt | |
9 | // and mangling ___chkstk would break the `jmp ___chkstk` instruction in __alloca | |
10 | ||
ea8adc8c | 11 | #[cfg(all(windows, target_env = "gnu", not(feature = "mangled-names")))] |
041b39d2 | 12 | #[naked] |
ea8adc8c | 13 | #[no_mangle] |
041b39d2 | 14 | pub unsafe fn ___chkstk_ms() { |
ea8adc8c XL |
15 | asm!(" |
16 | push %rcx | |
17 | push %rax | |
18 | cmp $$0x1000,%rax | |
19 | lea 24(%rsp),%rcx | |
20 | jb 1f | |
21 | 2: | |
22 | sub $$0x1000,%rcx | |
23 | test %rcx,(%rcx) | |
24 | sub $$0x1000,%rax | |
25 | cmp $$0x1000,%rax | |
26 | ja 2b | |
27 | 1: | |
28 | sub %rax,%rcx | |
29 | test %rcx,(%rcx) | |
30 | pop %rax | |
31 | pop %rcx | |
abe05a73 | 32 | ret" ::: "memory" : "volatile"); |
041b39d2 XL |
33 | intrinsics::unreachable(); |
34 | } | |
35 | ||
ea8adc8c | 36 | #[cfg(all(windows, target_env = "gnu", not(feature = "mangled-names")))] |
041b39d2 | 37 | #[naked] |
ea8adc8c | 38 | #[no_mangle] |
041b39d2 XL |
39 | pub unsafe fn __alloca() { |
40 | asm!("mov %rcx,%rax // x64 _alloca is a normal function with parameter in rcx | |
abe05a73 XL |
41 | jmp ___chkstk // Jump to ___chkstk since fallthrough may be unreliable" |
42 | ::: "memory" : "volatile"); | |
041b39d2 XL |
43 | intrinsics::unreachable(); |
44 | } | |
45 | ||
ea8adc8c | 46 | #[cfg(all(windows, target_env = "gnu", not(feature = "mangled-names")))] |
041b39d2 | 47 | #[naked] |
ea8adc8c | 48 | #[no_mangle] |
041b39d2 | 49 | pub unsafe fn ___chkstk() { |
abe05a73 XL |
50 | asm!( |
51 | " | |
ea8adc8c XL |
52 | push %rcx |
53 | cmp $$0x1000,%rax | |
54 | lea 16(%rsp),%rcx // rsp before calling this routine -> rcx | |
55 | jb 1f | |
56 | 2: | |
57 | sub $$0x1000,%rcx | |
58 | test %rcx,(%rcx) | |
59 | sub $$0x1000,%rax | |
60 | cmp $$0x1000,%rax | |
61 | ja 2b | |
62 | 1: | |
63 | sub %rax,%rcx | |
64 | test %rcx,(%rcx) | |
041b39d2 | 65 | |
ea8adc8c XL |
66 | lea 8(%rsp),%rax // load pointer to the return address into rax |
67 | mov %rcx,%rsp // install the new top of stack pointer into rsp | |
68 | mov -8(%rax),%rcx // restore rcx | |
69 | push (%rax) // push return address onto the stack | |
70 | sub %rsp,%rax // restore the original value in rax | |
abe05a73 XL |
71 | ret" |
72 | ::: "memory" : "volatile" | |
73 | ); | |
041b39d2 XL |
74 | intrinsics::unreachable(); |
75 | } | |
60c5eb7d XL |
76 | |
77 | // HACK(https://github.com/rust-lang/rust/issues/62785): x86_64-unknown-uefi needs special LLVM | |
78 | // support unless we emit the _fltused | |
79 | #[no_mangle] | |
80 | #[used] | |
81 | #[cfg(target_os = "uefi")] | |
82 | static _fltused: i32 = 0; |