]> git.lizzy.rs Git - rust.git/blob - src/rt/arch/x86_64/morestack.S
Merge branch 'master' of github.com:graydon/rust
[rust.git] / src / rt / arch / x86_64 / morestack.S
1     .text
2
3 // __morestack
4 //
5 // LLVM generates a call to this to allocate more stack space in a functiono
6 // prolog when we run out.
7
8 #if defined(__APPLE__) || defined(_WIN32)
9 #define RUST_NEW_STACK      _rust_new_stack
10 #define RUST_DEL_STACK      _rust_del_stack
11 #define MORESTACK           ___morestack
12 #else
13 #define RUST_NEW_STACK      rust_new_stack
14 #define RUST_DEL_STACK      rust_del_stack
15 #define MORESTACK           __morestack
16 #endif
17
18         // Naturally, nobody can agree as to
19         // which arguments should go in which
20         // registers:
21 #if defined(_WIN32)
22 #  define ARG0 %rcx
23 #  define ARG1 %rdx
24 #  define ARG2 %r8
25 #else
26 #  define ARG0 %rdi
27 #  define ARG1 %rsi
28 #  define ARG2 %rdx
29 #endif
30
31 .globl RUST_NEW_STACK
32 .globl RUST_DEL_STACK
33
34 .globl MORESTACK
35
36 MORESTACK:
37         // Hastily and probably incorrectly ported from i386 version.
38         // Actually this calling convention doens't make so much sense
39         // for x86_64...
40         mov %rcx, ARG0      // param 0: amount of space needed
41         mov %rdx, ARG2      // param 2: size of arguments
42         lea 8(%rsp),ARG1
43         call rust_new_stack_sym
44
45         mov (%rsp),%rdx        // Grab the return pointer.
46         inc %rdx               // Skip past the `ret`.
47         mov %rax,%rsp          // Switch to the new stack.
48         call *%rdx             // Enter the new function.
49
50         // Now the function that called us has returned, so we need to delete the
51         // old stack space.
52         call rust_new_stack_sym
53         mov %rax,%rsp          // Switch back to the old stack.
54         ret
55
56 // This is totally broken
57 rust_new_stack_sym:
58 rust_del_stack_sym: