]> git.lizzy.rs Git - rust.git/blob - src/rt/arch/x86_64/morestack.S
Remove FIXME question
[rust.git] / src / rt / arch / x86_64 / morestack.S
1 /*
2         __morestack
3
4         See i386/morestack.S for the lengthy, general explanation.
5 */
6
7 .text
8
9 #if defined(__APPLE__) || defined(_WIN32)
10 #define UPCALL_NEW_STACK        _upcall_new_stack
11 #define UPCALL_DEL_STACK        _upcall_del_stack
12 #define MORESTACK               ___morestack
13 #else
14 #define UPCALL_NEW_STACK        upcall_new_stack
15 #define UPCALL_DEL_STACK        upcall_del_stack
16 #define MORESTACK               __morestack
17 #endif
18
19 .globl UPCALL_NEW_STACK
20 .globl UPCALL_DEL_STACK
21 .globl MORESTACK
22
23 #if defined(__linux__) || defined(__FreeBSD__)
24         .hidden MORESTACK
25 #else
26 #if defined(__APPLE__)
27         .private_extern MORESTACK
28 #endif
29 #endif
30
31 #ifdef __ELF__
32         .type MORESTACK,@function
33 #endif
34
35
36 #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
37 MORESTACK:
38         .cfi_startproc
39
40         pushq %rbp
41         // The CFA is 24 bytes above the register that it will
42         // be associated with for this frame (%rbp). That is 8
43         // bytes greater than a normal frame, to allow the unwinder
44         // to skip the partial frame of the original function.
45         .cfi_def_cfa_offset 24
46         // %rbp is -24 bytes from the CFA
47         .cfi_offset %rbp, -24
48         movq %rsp, %rbp
49         // Calculate the CFA as on offset from %ebp
50         .cfi_def_cfa_register %rbp
51
52         subq $184, %rsp
53
54         // Save argument registers of the original function
55         movq %rdi,       (%rsp)
56         movq %rsi,      8(%rsp)
57         movq %rdx,     16(%rsp)
58         movq %rcx,     24(%rsp)
59         movq %r8,      32(%rsp)
60         movq %r9,      40(%rsp)
61         movdqa %xmm0,  48(%rsp)
62         movdqa %xmm1,  64(%rsp)
63         movdqa %xmm2,  80(%rsp)
64         movdqa %xmm3,  96(%rsp)
65         movdqa %xmm4, 112(%rsp)
66         movdqa %xmm5, 128(%rsp)
67         movdqa %xmm6, 144(%rsp)
68         movdqa %xmm7, 160(%rsp)
69
70         // Calculate the address of the stack arguments.
71         // We have the base pointer, __morestack's return address,
72         // and __morestack's caller's return address to skip
73         movq %rbp, %rax
74         addq $24, %rax  // Base pointer, return address x2
75
76         // The arguments to __morestack are passed in %r10 & %r11
77
78         movq %r11, %rdx // Size of stack arguments
79         movq %rax, %rsi // Address of stack arguments
80         movq %r10, %rdi // The amount of stack needed
81         
82 #ifdef __APPLE__
83         call UPCALL_NEW_STACK
84 #endif
85 #ifdef __linux__
86         call UPCALL_NEW_STACK@PLT
87 #endif
88 #ifdef __FreeBSD__
89         call UPCALL_NEW_STACK@PLT
90 #endif
91
92         // Pop the saved arguments
93         movq      (%rsp), %rdi
94         movq     8(%rsp), %rsi
95         movq    16(%rsp), %rdx
96         movq    24(%rsp), %rcx
97         movq    32(%rsp), %r8
98         movq    40(%rsp), %r9
99         movdqa  48(%rsp), %xmm0
100         movdqa  64(%rsp), %xmm1
101         movdqa  80(%rsp), %xmm2
102         movdqa  96(%rsp), %xmm3
103         movdqa 112(%rsp), %xmm4
104         movdqa 128(%rsp), %xmm5
105         movdqa 144(%rsp), %xmm6
106         movdqa 160(%rsp), %xmm7
107
108         addq $184, %rsp
109
110         movq 8(%rbp),%r10       // Grab the return pointer.
111         incq %r10               // Skip past the `ret` in our parent frame
112         movq %rax,%rsp          // Switch to the new stack.
113
114         call *%r10              // Reenter the caller function
115
116         // Switch back to the rust stack
117         movq %rbp, %rsp
118
119         // Save the return value
120         pushq %rax
121
122 #ifdef __APPLE__
123         call UPCALL_DEL_STACK
124 #endif
125 #ifdef __linux__
126         call UPCALL_DEL_STACK@PLT
127 #endif
128 #ifdef __FreeBSD__
129         call UPCALL_DEL_STACK@PLT
130 #endif
131
132         popq %rax // Restore the return value
133         popq %rbp
134         ret
135         
136         .cfi_endproc
137
138 #else
139 MORESTACK:
140         ret
141 #endif