task_stack_amd64.S raw

   1  #ifdef __MACH__ // Darwin
   2  .global  _moxie_startTask
   3  _moxie_startTask:
   4  #else // Linux etc
   5  .section .text.moxie_startTask
   6  .global  moxie_startTask
   7  moxie_startTask:
   8  #endif
   9      .cfi_startproc
  10      // Small assembly stub for starting a goroutine. This is already run on the
  11      // new stack, with the callee-saved registers already loaded.
  12      // Most importantly, r12 contain the pc of the to-be-started function and
  13      // r13 contain the only argument it is given. Multiple arguments are packed
  14      // into one by storing them in a new allocation.
  15  
  16      // Indicate to the unwinder that there is nothing to unwind, this is the
  17      // root frame. It avoids bogus extra frames in GDB like here:
  18      //     #10 0x00000000004277b6 in <goroutine wrapper> () at [...]
  19      //     #11 0x00000000004278f3 in moxie_startTask () at [...]
  20      //     #12 0x0000000000002030 in ?? ()
  21      //     #13 0x0000000000000071 in ?? ()
  22      .cfi_undefined rip
  23  
  24      // Set the first argument of the goroutine start wrapper, which contains all
  25      // the arguments.
  26      movq %r13, %rdi
  27  
  28      // Branch to the "goroutine start" function.
  29      callq *%r12
  30  
  31      // After return, exit this goroutine. This is a tail call.
  32      #ifdef __MACH__
  33      jmp _moxie_task_exit
  34      #else
  35      jmp moxie_task_exit
  36      #endif
  37      .cfi_endproc
  38  
  39  #ifdef __MACH__ // Darwin
  40  .global _moxie_swapTask
  41  _moxie_swapTask:
  42  #else // Linux etc
  43  .global moxie_swapTask
  44  .section .text.moxie_swapTask
  45  moxie_swapTask:
  46  #endif
  47      // This function gets the following parameters:
  48      // %rdi = newStack uintptr
  49      // %rsi = oldStack *uintptr
  50  
  51      // Save all callee-saved registers:
  52      pushq %r15
  53      pushq %r14
  54      pushq %r13
  55      pushq %r12
  56      pushq %rbp
  57      pushq %rbx
  58  
  59      // Save the current stack pointer in oldStack.
  60      movq %rsp, (%rsi)
  61  
  62      // Switch to the new stack pointer.
  63      movq %rdi, %rsp
  64  
  65      // Load saved register from the new stack.
  66      popq %rbx
  67      popq %rbp
  68      popq %r12
  69      popq %r13
  70      popq %r14
  71      popq %r15
  72  
  73      // Return into the new task, as if moxie_swapTask was a regular call.
  74      ret
  75  
  76  #ifdef __MACH__ // Darwin
  77  // allow these symbols to stripped as dead code
  78  .subsections_via_symbols
  79  #endif
  80