diff options
Diffstat (limited to 'libc/sysdeps/linux/kvx/getcontext.S')
| -rw-r--r-- | libc/sysdeps/linux/kvx/getcontext.S | 81 | 
1 files changed, 81 insertions, 0 deletions
| diff --git a/libc/sysdeps/linux/kvx/getcontext.S b/libc/sysdeps/linux/kvx/getcontext.S new file mode 100644 index 000000000..9440f67ce --- /dev/null +++ b/libc/sysdeps/linux/kvx/getcontext.S @@ -0,0 +1,81 @@ +/* + * 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 getcontext (ucontext_t *ucp) + */ +ENTRY(__getcontext) +	/* Save callee saved registers ($r14, $r18 - $r31) +	 * and some special registers */ + +	/* Save the entire occtuple, although we only need $sp and $r14 */ +	so MCONTEXT_Q12[$r0] = $r12r13r14r15 +	get $r4 = $lc +	;; +	/* Don't need to save veneer registers $r16 and $r17 */ +	sq (MCONTEXT_Q16 + 16)[$r0] = $r18r19 +	get $r5 = $le +	;; +	so MCONTEXT_Q20[$r0] = $r20r21r22r23 +	get $r6 = $ls +	;; +	so MCONTEXT_Q24[$r0] = $r24r25r26r27 +	get $r7 = $ra +	;; +	so MCONTEXT_Q28[$r0] = $r28r29r30r31 +	get $r8 = $cs +	;; +	so MCONTEXT_LC_LE_LS_RA[$r0] = $r4r5r6r7 +	/* Save ucp and $ra in callee saved registers because below we need to +	 * do a call to sigprocmask and afterwards we need to restore $ra. */ +	copyd $r20 = $r0 +	copyd $r21 = $r7 +	;; +	sd MCONTEXT_CS_SPC[$r0] = $r8 + +	/* Prepare call to sigprocmask */ +	make $r0 = SIG_BLOCK +	make $r1 = 0 +	;; +	/* $r20 points to the ucontext */ +	addd $r2 = $r20, UCONTEXT_SIGMASK +	/* Already set the return value for when this is called in the context +	 * of swapcontext. Because when this context returns it should look +	 * like as if swapcontext returned with 0. */ +	sd MCONTEXT_Q0[$r20] = $r1 +	;; +	/* sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask)) */ +	call sigprocmask +	;; +	/* Restore $ra to point to the caller of this function. So, +	 * __getcontext will return with -1 (set by __syscall_error) and an +	 * appropriate errno */ +	set $ra = $r21 +	;; +	/* Check return value of sigprocmask */ +	cb.deqz $r0 ? 1f +	;; +	goto __syscall_error +	;; +1: +	/* Restore used callee saved registers */ +	lq $r20r21 = MCONTEXT_Q20[$r20] +	;; +	/* Set return value */ +	make $r0 = 0 +	ret +	;; +END(__getcontext) +weak_alias(__getcontext, getcontext) | 
