blob: 7b91d21d978bc9f90c671330cc0699c5746f2f7b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
/*
* 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 setcontext (const ucontext_t *ucp)
*/
ENTRY(__setcontext)
get $r16 = $ra
addd $r12 = $r12, -32
;;
/* Save ucp pointer and $ra on the stack because we can't trash
* any callee saved registers in case __setcontext returns */
sd 16[$r12] = $r16
;;
sd 24[$r12] = $r0
;;
/* Bring back the signal status. */
make $r0 = SIG_SETMASK
addd $r1 = $r0, UCONTEXT_SIGMASK
make $r2 = 0
;;
/* sigprocmask(SIG_SETMASK, &(ucontext->uc_sigmask), NULL) */
call sigprocmask
;;
/* Check return value of sigprocmask */
cb.deqz $r0 ? 1f
/* Normally __setcontext does not return. But in case of an error it
* returns with -1 and an appropriate errno */
ld $r16 = 16[$r12]
;;
set $ra = $r16
addd $r12 = $r12, 32
;;
goto __syscall_error
;;
1:
/* Get back the ucp pointer */
ld $r16 = 24[$r12]
/* Reset the stack pointer (we can trash $ra here, because we will
* never return to after __setcontext from this point onwards) */
addd $r12 = $r12, 32
;;
/* Restore callee saved registers */
lq $r18r19 = (MCONTEXT_Q16 + 16)[$r16]
;;
/* Setup $r20, $r21 for the __startcontext to work */
lo $r20r21r22r23 = MCONTEXT_Q20[$r16]
;;
lo $r24r25r26r27 = MCONTEXT_Q24[$r16]
;;
lo $r28r29r30r31 = MCONTEXT_Q28[$r16]
;;
/* Restore special registers */
lo $r40r41r42r43 = MCONTEXT_LC_LE_LS_RA[$r16]
;;
/* Now load argument registers */
lo $r0r1r2r3 = MCONTEXT_Q0[$r16]
set $lc = $r40
;;
lo $r4r5r6r7 = MCONTEXT_Q4[$r16]
set $le = $r41
;;
lo $r8r9r10r11 = MCONTEXT_Q8[$r16]
set $ls = $r42
;;
/* Restore $sp */
ld $r12 = MCONTEXT_Q12[$r16]
/* Restore $ra which points to the $ra set by __getcontext or
* to__startcontext if __makecontext was called in between */
set $ra = $r43
;;
ld $r40 = MCONTEXT_CS_SPC[$r16]
;;
ld $r14 = (MCONTEXT_Q12 + 16)[$r16]
set $cs = $r40
;;
ret
;;
END(setcontext)
weak_alias(__setcontext, setcontext)
ENTRY(__startcontext)
icall $r21
;;
copyd $r0 = $r20
/* Check if the new context is 0 if so just call _exit */
cb.deqz $r20 ? 1f
;;
goto __setcontext
;;
/* This should never be reached otherwise kill the thread */
1: goto _exit
;;
END(__startcontext)
|