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