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