swap_stack_x64_sysv.S 3.34 KB
Newer Older
Kunshan Wang's avatar
Kunshan Wang committed
1 2
#include "asm_common.S.inc"

3 4
# swap_stack_to(new_sp: Address, entry: Address, old_sp_loc: Address)
#               %rdi             %rsi            %rdx
Kunshan Wang's avatar
Kunshan Wang committed
5
begin_func swap_to_mu_stack
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
          # -- on old stack --
          # C calling convention
          pushq %rbp
          movq %rsp, %rbp

          # other callee-saved registers
          pushq %rbx
          pushq %r12
          pushq %r13
          pushq %r14
          pushq %r15

          # save sp to %rbx
          movq %rsp, 0(%rdx)

          # switch to new stack
          movq %rdi, %rsp
          # save entry function in %rax
          movq %rsi, %rax

          # -- on new stack --
          # arguments (reverse order of thread.rs - runtime_load_args)
          popq %r9
          popq %r8
          popq %rcx
          popq %rdx
          popq %rsi
          popq %rdi
          movsd 0(%rsp), %xmm7
          movsd 8(%rsp), %xmm6
          movsd 16(%rsp), %xmm5
          movsd 24(%rsp), %xmm4
          movsd 32(%rsp), %xmm3
          movsd 40(%rsp), %xmm2
          add $48, %rsp
          # at this point new stack is clean (no intermediate values)

          movq %rsp, %rbp

          # push an empty pointer to stack, if entry fucntion tries to return, it causes a segfault
          pushq $0
          # push entry function and start it
          pushq %rax
          ret
Kunshan Wang's avatar
Kunshan Wang committed
50
end_func swap_to_mu_stack
51 52 53

# _swap_back_to_native_stack(sp_loc: Address)
#                            %rdi
Kunshan Wang's avatar
Kunshan Wang committed
54
begin_func muentry_swap_back_to_native_stack
55 56 57 58 59 60 61 62 63 64
          movq 0(%rdi), %rsp

          popq %r15
          popq %r14
          popq %r13
          popq %r12
          popq %rbx

          popq %rbp
          ret
Kunshan Wang's avatar
Kunshan Wang committed
65
end_func muentry_swap_back_to_native_stack
66 67

# _get_current_frame_rbp() -> Address
Kunshan Wang's avatar
Kunshan Wang committed
68
begin_func get_current_frame_rbp
69 70
          movq %rbp, %rax
          ret
Kunshan Wang's avatar
Kunshan Wang committed
71
end_func get_current_frame_rbp
qinsoon's avatar
qinsoon committed
72

73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
# muentry_throw_exception(obj: Address)
#                         %rdi
begin_func muentry_throw_exception
         # save all callee-saved
         pushq %r15
         pushq %r14
         pushq %r13
         pushq %r12
         pushq %rbp
         pushq %rbx

         # %rsp points to %rbx, pass this as 2nd argument
         movq  %rsp, %rsi

         jmp CNAME(throw_exception_internal)
         # won't return

qinsoon's avatar
qinsoon committed
90
# _exception_restore(dest: Address, callee_saved: *const Word, rsp: Address) -> !
91
#                    %rdi           %rsi                       %rdx
qinsoon's avatar
qinsoon committed
92
# callee_saved: [rbx, rbp, r12, r13, r14, r15]
Kunshan Wang's avatar
Kunshan Wang committed
93
begin_func exception_restore
qinsoon's avatar
qinsoon committed
94 95 96 97 98 99 100 101 102
          movq 0(%rsi), %rbx
          movq 8(%rsi), %rbp
          movq 16(%rsi),%r12
          movq 24(%rsi),%r13
          movq 32(%rsi),%r14
          movq 40(%rsi),%r15

          movq %rdx, %rsp
          jmpq *%rdi
Kunshan Wang's avatar
Kunshan Wang committed
103
end_func exception_restore
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130

# fake_swap_mu_thread(old_sp_loc: Address)
#                     %rdi
# (we do not actually swap stack, but we make the stack the same
# as if they are native stack that have been swapped out, so that
# when THREADEXIT (swap_back_to_native_stack) is called, we won't panic

# this function is untested!!!
begin_func fake_swap_mu_thread
    # save return address
    movq (%rsp), %rax

    pushq %rbp
    movq %rsp, %rbp

    pushq %rbx
    pushq %r12
    pushq %r13
    pushq %r14
    pushq %r15

    # save old sp to thread field
    movq %rsp, 0(%rdi)

    # return to caller, but preserve those pushed values (since THREADEXIT will pick them up)
    pushq %rax
    ret