Update copyright notices with scripts/update-copyrights
[jlayton/glibc.git] / ports / sysdeps / unix / sysv / linux / hppa / setcontext.S
1 /* Install given context.
2    Copyright (C) 2008-2014 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Helge Deller <deller@gmx.de>, 2008.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library.  If not, see
18    <http://www.gnu.org/licenses/>.  */
19
20 #include <sysdep.h>
21
22 #include "ucontext_i.h"
23
24
25 ENTRY(__setcontext)
26         /* Prologue */
27         stwm    %r3, 64(%sp)
28 #ifdef PIC
29         stw     %r19, -32(%sp)
30 #endif
31
32         /* Save ucp.  */
33         copy    %r26, %r3
34
35 .Lagain:
36         /* Set the current signal mask.  */
37         /* sigprocmask(SIG_BLOCK, &ucp->uc_sigmask, NULL);  */
38         copy    %r0, %r24
39         ldo     oSIGMASK(%r3), %r25
40         bl      sigprocmask, %r2
41         ldi     SIG_SETMASK, %r26
42
43         comib,<>,n 0,%ret0,.Lerror
44
45         /* Save %sp, %dp.  */
46         copy    %sp, %r4
47         copy    %dp, %r5
48         copy    %r19, %r6
49
50         /* Get the registers.  */
51         ldw     oR1(%r3), %r1
52         ldw     oR2(%r3), %r2
53         /* ldw  oR3(%r3), %r3 - used for ucp pointer.   */
54         /* ldw  oR4(%r3), %r4 - used for original %sp.  */
55         /* ldw  oR5(%r3), %r5 - used for %dp / %r27.    */
56         /* ldw  oR6(%r3), %r6 - used for %r19.          */
57         ldw     oR7(%r3), %r7
58         ldw     oR8(%r3), %r8
59         ldw     oR9(%r3), %r9
60         ldw     oR10(%r3), %r10
61         ldw     oR11(%r3), %r11
62         ldw     oR12(%r3), %r12
63         ldw     oR13(%r3), %r13
64         ldw     oR14(%r3), %r14
65         ldw     oR15(%r3), %r15
66         ldw     oR16(%r3), %r16
67         ldw     oR17(%r3), %r17
68         ldw     oR18(%r3), %r18
69         ldw     oR19(%r3), %r19
70         ldw     oR20(%r3), %r20
71         ldw     oR21(%r3), %r21
72         /* ldw  oR22(%r3), %r22 - dyncall arg.  */
73         ldw     oR23(%r3), %r23
74         ldw     oR24(%r3), %r24
75         ldw     oR25(%r3), %r25
76         ldw     oR26(%r3), %r26
77         ldw     oR27(%r3), %r27
78         ldw     oR28(%r3), %r28
79         ldw     oR29(%r3), %r29
80         ldw     oR30(%r3), %sp
81         /* ldw  oR31(%r3), %r31 - dyncall scratch register */
82
83         /* Restore floating-point registers.  */
84         ldo      oFPREGS31(%r3), %r22
85         fldds     0(%r22), %fr31
86         fldds,mb -8(%r22), %fr30
87         fldds,mb -8(%r22), %fr29
88         fldds,mb -8(%r22), %fr28
89         fldds,mb -8(%r22), %fr27
90         fldds,mb -8(%r22), %fr26
91         fldds,mb -8(%r22), %fr25
92         fldds,mb -8(%r22), %fr24
93         fldds,mb -8(%r22), %fr23
94         fldds,mb -8(%r22), %fr22
95         fldds,mb -8(%r22), %fr21
96         fldds,mb -8(%r22), %fr20
97         fldds,mb -8(%r22), %fr19
98         fldds,mb -8(%r22), %fr18
99         fldds,mb -8(%r22), %fr17
100         fldds,mb -8(%r22), %fr16
101         fldds,mb -8(%r22), %fr15
102         fldds,mb -8(%r22), %fr14
103         fldds,mb -8(%r22), %fr13
104         fldds,mb -8(%r22), %fr12
105         fldds,mb -8(%r22), %fr11
106         fldds,mb -8(%r22), %fr10
107         fldds,mb -8(%r22), %fr9
108         fldds,mb -8(%r22), %fr8
109         fldds,mb -8(%r22), %fr7
110         fldds,mb -8(%r22), %fr6
111         fldds,mb -8(%r22), %fr5
112         fldds,mb -8(%r22), %fr4
113         fldds,mb -8(%r22), %fr3
114         fldds,mb -8(%r22), %fr2
115         fldds,mb -8(%r22), %fr1
116         fldds,mb -8(%r22), %fr0
117
118         /* Do not load oSS_SP into %sp. The value of oSS_SP indicates
119            the start of the user allocated stack, but not the sp that
120            should be used by the new context. In fact makecontext
121            will create a frame, and adjust sp as required. We do not
122            support calling getcontext and modifying ss_sp without
123            a call to makecontext to synchronize ss_sp into the machine
124            context.  */
125
126         /* Call external function.  */
127         copy    %r2, %r22
128         bl      $$dyncall, %r31
129         copy    %r31, %r2
130
131         /* We return here. Get new ucp in %r3, reload %sp.  */
132         ldw     oUC_LINK(%r3), %r3
133         copy    %r4, %sp
134         copy    %r5, %dp
135         copy    %r6, %r19
136
137         /* Continue until ucp == NULL.  */
138         comib,<> 0,%r3,.Lagain
139         nop
140
141         /* No further context available. Exit now.  */
142         bl      _exit, %r2
143         ldi     -1, %r26
144
145
146 .Lerror:
147         /* Epilogue */
148         ldw     -84(%r30), %r2
149 #ifdef PIC
150         ldw     -96(%r30), %r19
151 #endif
152         bv      %r0(%r2)
153         ldwm    -64(%r30), %r3
154 L(pseudo_end):
155 PSEUDO_END(__setcontext)
156
157 weak_alias(__setcontext, setcontext)