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