Update copyright dates with scripts/update-copyrights.
[glibc.git] / sysdeps / unix / sysv / linux / sparc / sparc32 / setcontext.S
blob19651525fc52dd1b4b5d078f47d0fd5f629ab6b3
1 /* Install given context.
2    Copyright (C) 2008-2015 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by David S. Miller <davem@davemloft.net>, 2008.
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.
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.
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/>.  */
20 #include <sysdep.h>
21 #include <sys/trap.h>
23 #include "ucontext_i.h"
26 /*  int __setcontext (const ucontext_t *ucp)
28   Restores the machine context in UCP and thereby resumes execution
29   in that context.
31   This implementation is intended to be used for *synchronous* context
32   switches only.  Therefore, it does not have to restore anything
33   other than the PRESERVED state.  */
35 ENTRY(__setcontext)
36         save    %sp, -112, %sp
38         mov     SIG_SETMASK, %o0
39         add     %i0, UC_SIGMASK, %o1
40         clr     %o2
41         mov     8, %o3
42         mov     __NR_rt_sigprocmask, %g1
43         ta      0x10
45         /* This is a bit on the expensive side, and we could optimize
46            the unwind similar to how the 32-bit sparc longjmp code
47            does if performance of this routine really matters.  */
48         ta      ST_FLUSH_WINDOWS
50         ldub    [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_EN], %g1
51         cmp     %g1, 0
52         be      1f
53          nop
54         ld      [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_FSR], %fsr
55         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D0], %f0
56         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D2], %f2
57         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D4], %f4
58         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D6], %f6
59         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D8], %f8
60         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D10], %f10
61         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D12], %f12
62         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D14], %f14
63         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D16], %f16
64         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D18], %f18
65         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D20], %f20
66         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D22], %f22
67         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D24], %f24
68         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D26], %f26
69         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D28], %f28
70         ldd     [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D30], %f30
72         ld      [%i0 + UC_MCONTEXT + MC_GREGS + GREG_Y], %g1
73         wr      %g1, 0x0, %y
75         /* We specifically do not restore %g1 since we need it here as
76            a temporary.  */
77         ld      [%i0 + UC_MCONTEXT + MC_GREGS + GREG_G2], %g2
78         ld      [%i0 + UC_MCONTEXT + MC_GREGS + GREG_G3], %g3
79         ld      [%i0 + UC_MCONTEXT + MC_GREGS + GREG_G4], %g4
80         ld      [%i0 + UC_MCONTEXT + MC_GREGS + GREG_G5], %g5
81         ld      [%i0 + UC_MCONTEXT + MC_GREGS + GREG_G6], %g6
82         ld      [%i0 + UC_MCONTEXT + MC_GREGS + GREG_G7], %g7
83         ld      [%i0 + UC_MCONTEXT + MC_GREGS + GREG_O1], %i1
84         ld      [%i0 + UC_MCONTEXT + MC_GREGS + GREG_O2], %i2
85         ld      [%i0 + UC_MCONTEXT + MC_GREGS + GREG_O3], %i3
86         ld      [%i0 + UC_MCONTEXT + MC_GREGS + GREG_O4], %i4
87         ld      [%i0 + UC_MCONTEXT + MC_GREGS + GREG_O5], %i5
88         ld      [%i0 + UC_MCONTEXT + MC_GREGS + GREG_O6], %i6
89         restore
90         ld      [%o0 + UC_MCONTEXT + MC_GREGS + GREG_O7], %o7
91         ld      [%o0 + UC_MCONTEXT + MC_GREGS + GREG_PC], %g1
92         jmpl    %g1, %g0
93          ld     [%o0 + UC_MCONTEXT + MC_GREGS + GREG_O0], %o0
94 END(__setcontext)
96 weak_alias (__setcontext, setcontext)
98 /* This is the helper code which gets called if a function which is
99    registered with 'makecontext' returns.  In this case we have to
100    install the context listed in the uc_link element of the context
101    'makecontext' manipulated at the time of the 'makecontext' call.
102    If the pointer is NULL the process must terminate.  */
104 ENTRY(__start_context)
105         ld      [%sp + (16 * 4)], %g1
106         cmp     %g1, 0
107         be,a    1f
108          clr    %o0
109         call    __setcontext
110          mov    %g1, %o0
111         /* If this returns (which can happen if the syscall fails) we'll
112            exit the program with the return error value (-1).  */
113 1:      call    HIDDEN_JUMPTARGET(exit)
114          nop
115         /* The 'exit' call should never return.  In case it does cause
116            the process to terminate.  */
117         unimp
118 END(__start_context)