On Clang, this is __attribute__((preserve_none)), on MSVC, __preserve_none.
Either way, the result is a calling convention where almost all registers are considered volatile, and is much less verbose than inline assembly register clobbering syntax.
RSP and RBP are non-volatile, and the MSVC version, R12 too. But everything else, if the compiler uses it, the compiler saves it on calling. Of course, floating point registers are volatile already.
The result is a context switch that looks like this:
Code: Select all
;__preserve_none calling convention
;R13 - Current context pointer [save destination, load source]
swap_context_x64@@_A PROC
;Save and restore GPRs
xchg r12, [r13 + CONTEXT_T.rg_r12]
xchg rbp, [r13 + CONTEXT_T.rg_rbp]
xchg rsp, [r13 + CONTEXT_T.rg_rsp]
;Now on the other context stack
;Make the jump
mov rax, [r13 + CONTEXT_T.rg_rip]
mov rdx, finish_pnone
mov [r13 + CONTEXT_T.rg_rip], rdx
push rax
ret
finish_pnone LABEL PROC
ret
swap_context_x64@@_A ENDP

