From 9695ea005d4af93dcd60f74f10fd3c54499a182f Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Thu, 11 Nov 2021 16:31:58 -0800 Subject: chore: split up base library into individual files for smaller binaries --- sys/base/coro/unix_x64.s | 113 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 sys/base/coro/unix_x64.s (limited to 'sys/base/coro/unix_x64.s') diff --git a/sys/base/coro/unix_x64.s b/sys/base/coro/unix_x64.s new file mode 100644 index 0000000..d7de2a2 --- /dev/null +++ b/sys/base/coro/unix_x64.s @@ -0,0 +1,113 @@ +; Nicholas Noll 2019 +; +; =================================================================== +%use altreg + + bits 64 + default rel + global _newcoro + global _coroyield + +; =================================================================== + section .text +; ------------------------------------------------------------------- + +%assign L.coro -8 +%assign L.func -16 + +coroinit: + mov R7, [RBP + L.coro] + mov R6, R0 + call [RBP + L.func] + +rerun: + mov R7, [RBP + L.coro] + mov R6, R0 + call _coroyield + jmp rerun + +; ------------------------------------------------------------------- +; # Register Mapping +; +; R0 R1 R2 R3 R4 R5 R6 R7 R8 ... +; RAX RCX RDX RBX RSP RBP RSI RDI R8 ... +; +; # Sys V calling convention +; func(R7, R6, R2, R1, R8, R9, Z0-7): R0 +; +; # Stack layout of an in-flight coro +; *coro +; *func +; *bp (base pointer of stack) +; ....... STACK ......... +; Saved Clobbers +; +; ### +; Stack layout of an init coro +; Stores the func pointer to init +; Stores the clobber registers. +; +; L.coro [8] +; L.func [7] +; coroinit [6] +; RBP [5] +; R3 [4] +; R12 [3] +; R13 [2] +; R14 [1] +; R15 [0] + +%define WORDSZ 8 +%define NSAVES 9 + +; coro *coro·new(co *coro, fn func, bp *stack) +_newcoro: + lea R0, [coroinit] ; Store address of init function + lea R1, [R2 - NSAVES*WORDSZ] ; Store offset address of stack + + mov [R1 + 8*WORDSZ], R7 ; Store context pointer + mov [R1 + 7*WORDSZ], R6 ; Store function pointer + mov [R1 + 6*WORDSZ], R0 ; Store initializer pointer + mov [R1 + 5*WORDSZ], R2 ; Store stack base pointer + + xor R0, R0 + + ; Start of mutable stack + ; Blank out the clobbers + mov [R1 + 4*WORDSZ], R0 ; R3 + mov [R1 + 3*WORDSZ], R0 ; R12 + mov [R1 + 2*WORDSZ], R0 ; R13 + mov [R1 + 1*WORDSZ], R0 ; R14 + mov [R1 + 0*WORDSZ], R0 ; R15 + + mov [R7], R1 + ret + +; Saves register state +%macro pushclobs 0 + push RBP + push R3 + push R12 + push R13 + push R14 + push R15 +%endmacro + +; Restores register state +%macro popclobs 0 + pop R15 + pop R14 + pop R13 + pop R12 + pop R3 + pop RBP +%endmacro + +; uintptr coro.yield(co *coro, data uintptr) +_coroyield: + pushclobs + mov R0, R6 ; Move return value into return register. + xchg RSP, [R7] ; Atomically swap the stack pointer with the yieldee. + popclobs + + ret -- cgit v1.2.1