diff options
Diffstat (limited to 'libc/sysdeps/linux/kvx/swapcontext.S')
| -rw-r--r-- | libc/sysdeps/linux/kvx/swapcontext.S | 63 | 
1 files changed, 63 insertions, 0 deletions
| diff --git a/libc/sysdeps/linux/kvx/swapcontext.S b/libc/sysdeps/linux/kvx/swapcontext.S new file mode 100644 index 000000000..1abb6a8a8 --- /dev/null +++ b/libc/sysdeps/linux/kvx/swapcontext.S @@ -0,0 +1,63 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive for + * more details. + * + * Copyright (C) 2025 Kalray Inc. + * Author(s): Julian Vetter <jvetter@kalrayinc.com> + */ + +#include <sysdep.h> + +#include "ucontext_i.h" + +	.text + +/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ + +ENTRY(swapcontext) +	/* Make space on the stack to save all caller saved registers */ +	get $r16 = $ra +	addd $r12 = $r12, -32 +	;; + +	/* Save $ra on the stack */ +	sd (24)[$r12] = $r16 +	;; +	/* Save the arguments of swapcontext on the stack */ +	sq (8)[$r12] = $r0r1 +	;; +	call __getcontext +	;; + +	/* Save the return value of __getcontext in $r17 */ +	copyd $r17 = $r0 + +	/* Restore $ra */ +	ld $r16 = (24)[$r12] +	;; +	/* Restore arguments */ +	lq $r0r1 = (8)[$r12] +	/* Readjust the stack pointer */ +	addd $r12 = $r12, 32 +	/* Also restore $ra */ +	set $ra = $r16 +	;; + +	/* Exit if getcontext() failed */ +	cb.deqz $r17 ? 1f +	;; + +	/* Set the return value set by __syscall_error in __getcontext */ +	copyd $r0 = $r17 +	ret +	;; +1: +	/* Store the $sp and $ra in the context to be saved */ +	sd (MCONTEXT_Q12)[$r0] = $r12 +	;; +	sd (MCONTEXT_LC_LE_LS_RA + 24)[$r0] = $r16 +	copyd $r0 = $r1 +	goto __setcontext +	;; +END(swapcontext) | 
