1/* Copyright (C) 2001-2022 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
17
18#include <sysdep.h>
19#include <features.h>
20
21#include "ucontext_i.h"
22
23/* __setcontext (const ucontext_t *ucp)
24
25 Restores the machine context in UCP and thereby resumes execution
26 in that context.
27
28 This implementation in intended to be used for *synchronous* context
29 switches only. Therefore, it does not have to restore anything
30 other than the PRESERVED state. */
31
32ENTRY(__setcontext)
33 .prologue
34 .body
35 alloc r11 = ar.pfs, 1, 0, 4, 0
36
37 // sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL):
38
39 mov r3 = SC_MASK
40 mov out0 = SIG_SETMASK
41 ;;
42 add out1 = r3, in0
43 mov out2 = 0
44 mov out3 = 8 // sizeof kernel sigset_t
45
46 invala
47 DO_CALL(__NR_rt_sigprocmask)
48 add r2 = SC_NAT, r32
49
50 add r3 = SC_RNAT, r32 // r3 <- &sc_ar_rnat
51 add rPOS = SC_GR, r32 // rPOS <- &sc_gr[0]
52 ;;
53 ld8 rNAT = [r2], (SC_BSP-SC_NAT)
54 extr.u rPOS = rPOS, 3, 6 // get NaT bit number for r0
55 ;;
56 ld8 rBSP = [r2], (SC_UNAT-SC_BSP)
57 ld8 rRNAT = [r3], (SC_FPSR-SC_RNAT)
58 /*
59 * Rotate NaT bits by rPOS positions to the left:
60 */
61 sub rCPOS = 64, rPOS
62 ;;
63 ld8 rUNAT = [r2], (SC_PFS-SC_UNAT)
64 ld8 rFPSR = [r3], (SC_LC-SC_FPSR)
65 shl rTMP = rNAT, rPOS
66 ;;
67 ld8 rPFS = [r2], (SC_PR-SC_PFS)
68 ld8 rLC = [r3], (SC_BR+0*8-SC_LC)
69 shr.u rNAT = rNAT, rCPOS
70 ;;
71 ld8 rPR = [r2], (SC_BR+1*8-SC_PR)
72 ld8 rB0 = [r3], 16
73 or rNAT = rNAT, rTMP
74 ;;
75 ld8 rB1 = [r2], 16
76 ld8 rB2 = [r3], 16
77 ;;
78 mov.m ar.unat = rNAT
79 mov.m rRSC = ar.rsc
80 ;;
81 ld8 rB3 = [r2], 16
82 ld8 rB4 = [r3], (SC_GR+1*8-(SC_BR+4*8))
83 ;;
84 ld8 rB5 = [r2], (SC_GR+4*8-(SC_BR+5*8))
85 ld8.fill r1 = [r3], (5*8 - 1*8)
86 ;;
87 ld8.fill r4 = [r2], 16
88 ld8.fill r5 = [r3], 16
89 mov b0 = rB0
90 ;;
91 ld8.fill r6 = [r2], 48
92 ld8.fill r7 = [r3], (SC_FR+2*16-(SC_GR+7*8))
93 ;;
94 ld8.fill sp = [r2], (SC_FR+3*16-(SC_GR+12*8))
95 mov.m ar.fpsr = rFPSR
96 mov.i ar.pfs = rPFS
97 ;;
98 ldf.fill f3 = [r2], 16
99 ldf.fill f2 = [r3], 48
100 mov b1 = rB1
101 ;;
102 ldf.fill f4 = [r2], (16*16-4*16)
103 ldf.fill f5 = [r3], (17*16-5*16)
104 mov b2 = rB2
105 ;;
106 ldf.fill f16 = [r2], 32
107 ldf.fill f17 = [r3], 32
108 mov b3 = rB3
109 ;;
110 ldf.fill f18 = [r2], 32
111 ldf.fill f19 = [r3], 32
112 mov b4 = rB4
113 ;;
114 ldf.fill f20 = [r2], 32
115 ldf.fill f21 = [r3], 32
116 mov b5 = rB5
117 ;;
118 ldf.fill f22 = [r2], 32
119 ldf.fill f23 = [r3], 32
120 mov r8 = 0
121 ;;
122 ldf.fill f24 = [r2], 32
123 ldf.fill f25 = [r3], 32
124 mov r9 = 0
125 ;;
126 ldf.fill f26 = [r2], 32
127 ldf.fill f27 = [r3], 32
128 dep rTMP = 0, rRSC, 16, 14 // clear ar.rsc.loadrs
129 ;;
130 ldf.fill f28 = [r2], 32
131 ldf.fill f29 = [r3], 32
132 and rTMP = ~0x3, rTMP // clear ar.rsc.mode
133 ;;
134 ldf.fill f30 = [r2], 32
135 ldf.fill f31 = [r3], 32
136 mov pr = rPR, -1
137 ;;
138 mov.m ar.rsc = rTMP // put RSE into enforced lazy mode
139 ;;
140 loadrs // drop dirty partition
141 ;;
142 mov.m ar.bspstore = rBSP
143 mov.m ar.unat = rUNAT
144 mov.i ar.lc = rLC
145 ;;
146 mov.m ar.rnat = rRNAT
147 mov.m ar.rsc = rRSC
148 ret
149END(__setcontext)
150
151weak_alias (__setcontext, setcontext)
152

source code of glibc/sysdeps/unix/sysv/linux/ia64/setcontext.S