]> git.lizzy.rs Git - rust.git/commitdiff
rt: Implement part of the 64-bit __morestack
authorBrian Anderson <banderson@mozilla.com>
Tue, 29 Nov 2011 00:25:45 +0000 (16:25 -0800)
committerBrian Anderson <banderson@mozilla.com>
Tue, 29 Nov 2011 00:29:52 +0000 (16:29 -0800)
src/rt/arch/x86_64/morestack.S
src/rt/rust_task.cpp

index b8cc4c2b9c4b9c3955ab2f912027911cc826d132..1e51a3167c6e5e067f0401e1adcbc2b13d22831b 100644 (file)
@@ -6,12 +6,14 @@
 // prolog when we run out.
 
 #if defined(__APPLE__) || defined(_WIN32)
-#define RUST_NEW_STACK      _rust_new_stack
+#define RUST_NEW_STACK2     _rust_new_stack2
 #define RUST_DEL_STACK      _rust_del_stack
+#define UPCALL_CALL_C       _upcall_call_shim_on_c_stack
 #define MORESTACK           ___morestack
 #else
-#define RUST_NEW_STACK      rust_new_stack
+#define RUST_NEW_STACK2     rust_new_stack2
 #define RUST_DEL_STACK      rust_del_stack
+#define UPCALL_CALL_C       upcall_call_shim_on_c_stack
 #define MORESTACK           __morestack
 #endif
 
 #  define ARG2 %rdx
 #endif
 
-.globl RUST_NEW_STACK
+.globl RUST_NEW_STACK2
 .globl RUST_DEL_STACK
-
+.globl UPCALL_CALL_C
 .globl MORESTACK
 
+#ifdef __ELF__
+       .type MORESTACK,@function
+#endif
+
 MORESTACK:
-        // Hastily and probably incorrectly ported from i386 version.
-        // Actually this calling convention doens't make so much sense
-        // for x86_64...
-        mov %rcx, ARG0      // param 0: amount of space needed
-        mov %rdx, ARG2      // param 2: size of arguments
-        lea 8(%rsp),ARG1
-        call rust_new_stack_sym
+       .cfi_startproc
+
+       # Set up a normal backtrace
+       pushq %rbp
+       .cfi_def_cfa_offset 16
+       .cfi_offset %rbp, -16
+       movq %rsp, %rbp
+       .cfi_def_cfa_register %rbp
 
+       // Save argument registers
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rdx
+       pushq   %rcx
+       pushq   %r8
+       pushq   %r9
+
+       // Calculate the address of the stack arguments
+       movq %rbp, %rcx
+       addq $16, %rcx   // Add the saved %rbp, and return address
+       addq %r11, %rcx // Add the size of stack arguments
+
+       pushq %r10 // The amount of stack needed
+       pushq %rcx // Address of stack arguments
+       pushq %r11 // Size of stack arguments
+       pushq %rbp // Save the Rust stack pointer
+
+       // FIXME: Don't understand why I have to use the PLT here
+       lea RUST_NEW_STACK2@PLT(%rip), %rsi
+       lea 24(%rsp), %rdi
+       call UPCALL_CALL_C@PLT
+       
         mov (%rsp),%rdx        // Grab the return pointer.
         inc %rdx               // Skip past the `ret`.
         mov %rax,%rsp          // Switch to the new stack.
         call *%rdx             // Enter the new function.
 
-        // Now the function that called us has returned, so we need to delete the
-        // old stack space.
-        call rust_new_stack_sym
-        mov %rax,%rsp          // Switch back to the old stack.
-        ret
-
-// This is totally broken
-rust_new_stack_sym:
-rust_del_stack_sym:
\ No newline at end of file
+       .cfi_endproc
\ No newline at end of file
index 30489b1d66926ad4a2eb286dc4ca1f6b12908c93..3933692f0155613f9f681ccc30d22d0d5fca4345 100644 (file)
@@ -86,6 +86,21 @@ rust_new_stack(size_t stk_sz, void *args_addr, size_t args_sz,
     return new_sp;
 }
 
+struct rust_new_stack2_args {
+  size_t stk_sz;
+  void *args_addr;
+  size_t args_sz;
+  uintptr_t current_sp;
+};
+
+// A new stack function suitable for calling through
+// upcall_call_shim_on_c_stack
+extern "C" void *
+rust_new_stack2(struct rust_new_stack2_args *args) {
+    return rust_new_stack(args->stk_sz, args->args_addr,
+                          args->args_sz, args->current_sp);
+}
+
 extern "C" void
 rust_del_stack() {
     rust_task *task = rust_scheduler::get_task();