diff options
author | Julian Vetter <jvetter@kalrayinc.com> | 2025-08-26 14:42:27 +0200 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2025-09-21 08:08:36 +0200 |
commit | 77d35096a0bb9b9ac8acce75d95d80dab0f1205c (patch) | |
tree | 09bf66334b8e05d86c3bcfe1c229892761246b6a /libc/sysdeps/linux/kvx/makecontext.c | |
parent | a3d56d059df62b4ad6eb5ddb9edd1bb59609397a (diff) |
libc: kvx: add {get,set,swap,make}context functions
Add the obsolescent SUSv3 family of user context manipulating functions
for kvx.
Signed-off-by: Julian Vetter <jvetter@kalrayinc.com>
Diffstat (limited to 'libc/sysdeps/linux/kvx/makecontext.c')
-rw-r--r-- | libc/sysdeps/linux/kvx/makecontext.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/kvx/makecontext.c b/libc/sysdeps/linux/kvx/makecontext.c new file mode 100644 index 000000000..a52eded9f --- /dev/null +++ b/libc/sysdeps/linux/kvx/makecontext.c @@ -0,0 +1,53 @@ +/* + * 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 <stdarg.h> +#include <ucontext.h> + + +/* Number of arguments that go in registers. */ +#define NREG_ARGS 12 + +/* Take a context previously prepared via getcontext() and set to + call func() with the given int only args. */ +void +__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) +{ + extern void __startcontext (void); + unsigned long *funcstack; + va_list vl; + unsigned long *regptr; + unsigned int reg; + + /* Start at the top of stack. */ + funcstack = (unsigned long *) (ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + funcstack -= argc < NREG_ARGS ? 0 : argc - NREG_ARGS; + funcstack = (unsigned long *) (((uintptr_t) funcstack & -32L)); + + ucp->uc_mcontext.sc_regs.r12 = (unsigned long) funcstack; + /* Use $r20 and $r21 to pass some infos to __startcontext */ + ucp->uc_mcontext.sc_regs.r20 = (unsigned long) ucp->uc_link; + ucp->uc_mcontext.sc_regs.r21 = (unsigned long) func; + ucp->uc_mcontext.sc_regs.ra = (unsigned long) __startcontext; + + va_start (vl, argc); + + /* The first twelve arguments go into registers. */ + regptr = &(ucp->uc_mcontext.sc_regs.r0); + + for (reg = 0; (reg < argc) && (reg < NREG_ARGS); reg++) + *regptr++ = va_arg (vl, unsigned long); + + /* And the remainder on the stack. */ + for (; reg < argc; reg++) + *funcstack++ = va_arg (vl, unsigned long); + + va_end (vl); +} +weak_alias (__makecontext, makecontext) |