1 /* Create new context for ARC.
2 Copyright (C) 2020-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
22 #include <sys/ucontext.h>
25 __makecontext (ucontext_t
*ucp
, void (*func
) (void), int argc
, ...)
27 extern void __startcontext (void) attribute_hidden
;
28 unsigned long int sp
, *r
;
30 int i
, reg_args
, stack_args
;
32 sp
= ((unsigned long int) ucp
->uc_stack
.ss_sp
+ ucp
->uc_stack
.ss_size
) & ~7;
34 ucp
->uc_mcontext
.__sp
= sp
;
35 ucp
->uc_mcontext
.__fp
= 0;
37 /* __startcontext is sort of trampoline to invoke @func
38 From setcontext pov, the resume address is __startcontext,
39 set it up in BLINK place holder. */
41 ucp
->uc_mcontext
.__blink
= (unsigned long int) &__startcontext
;
43 /* __startcontext passed 2 types of args
44 - args to @func setup in canonical r0-r7
45 - @func and next function in r14,r15. */
47 ucp
->uc_mcontext
.__r14
= (unsigned long int) func
;
48 ucp
->uc_mcontext
.__r15
= (unsigned long int) ucp
->uc_link
;
50 r
= &ucp
->uc_mcontext
.__r0
;
54 reg_args
= argc
> 8 ? 8 : argc
;
55 for (i
= 0; i
< reg_args
; i
++)
56 *r
-- = va_arg (vl
, unsigned long int);
58 stack_args
= argc
- reg_args
;
60 if (__glibc_unlikely (stack_args
> 0))
62 sp
-= stack_args
* sizeof (unsigned long int);
63 ucp
->uc_mcontext
.__sp
= sp
;
64 r
= (unsigned long int *) sp
;
66 for (i
= 0; i
< stack_args
; i
++)
67 *r
++ = va_arg (vl
, unsigned long int);
73 weak_alias (__makecontext
, makecontext
)