5 // LLVM generates a call to this to allocate more stack space in a functiono
6 // prolog when we run out.
8 #if defined(__APPLE__) || defined(_WIN32)
9 #define UPCALL_NEW_STACK _upcall_new_stack
10 #define UPCALL_DEL_STACK _upcall_del_stack
11 #define UPCALL_CALL_C _upcall_call_shim_on_c_stack
12 #define MORESTACK ___morestack
14 #define UPCALL_NEW_STACK upcall_new_stack
15 #define UPCALL_DEL_STACK upcall_del_stack
16 #define UPCALL_CALL_C upcall_call_shim_on_c_stack
17 #define MORESTACK __morestack
20 // Naturally, nobody can agree as to
21 // which arguments should go in which
33 .globl UPCALL_NEW_STACK
34 .globl UPCALL_DEL_STACK
38 // FIXME: What about _WIN32?
39 #if defined(__linux__)
42 #if defined(__APPLE__)
43 .private_extern MORESTACK
48 .type MORESTACK,@function
51 #if defined(__linux__) || defined(__APPLE__)
57 // Set up a normal backtrace
60 .cfi_def_cfa_offset 16
65 .cfi_def_cfa_register %rbp
68 // FIXME: libgcc also saves rax. not sure if we need to
70 // Save argument registers
78 // Calculate the address of the stack arguments.
79 // We have the base pointer, __morestack's return address,
80 // and __morestack's caller's return address to skip
82 addq $24, %rcx // Base pointer, return address x2
86 pushq %r11 // Size of stack arguments
87 pushq %rcx // Address of stack arguments
88 pushq %r10 // The amount of stack needed
89 pushq $0 // Out pointer
91 movq UPCALL_NEW_STACK@GOTPCREL(%rip), %rsi
97 call UPCALL_CALL_C@PLT
100 // Pop the new_stack_args struct
104 // Pop the saved arguments
112 movq 8(%rbp),%r10 // Grab the return pointer.
113 incq %r10 // Skip past the `ret` in our parent frame
114 movq %rax,%rsp // Switch to the new stack.
116 call *%r10 // Reenter the caller function
118 // Switch back to the rust stack
121 // Align the stack again
124 movq UPCALL_DEL_STACK@GOTPCREL(%rip), %rsi
130 call UPCALL_CALL_C@PLT