Update copyright dates with scripts/update-copyrights.
[glibc.git] / sysdeps / unix / sysv / linux / mips / setcontext.S
blobf94940f5837ed9d395bd6f3a0fd6588200033d2b
1 /* Set current context.
2    Copyright (C) 2009-2015 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Maciej W. Rozycki <macro@codesourcery.com>.
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/asm.h>
22 #include <sys/fpregdef.h>
23 #include <sys/regdef.h>
25 #include "ucontext_i.h"
27 /* int setcontext (const ucontext_t *ucp) */
29         .text
30         .set    nomips16
31 LOCALSZ = 0
32 ARGSZ = 0
33 MASK = 0x00000000
34 #ifdef __PIC__
35 LOCALSZ = 1                                             /* save gp */
36 #endif
37 #if _MIPS_SIM != _ABIO32
38 ARGSZ = 1                                               /* save a0 */
39 # ifdef __PIC__
40 MASK = 0x10000000
41 # endif
42 #endif
43 FRAMESZ = (((ARGSZ + LOCALSZ) * SZREG) + ALSZ) & ALMASK
44 GPOFF = FRAMESZ - ((ARGSZ + 1) * SZREG)
45 #if _MIPS_SIM != _ABIO32
46 A0OFF = FRAMESZ - (1 * SZREG)                           /* callee-allocated */
47 #else
48 A0OFF = FRAMESZ + (0 * SZREG)                           /* caller-allocated */
49 #endif
51 NESTED (__setcontext, FRAMESZ, ra)
52         .mask   MASK, -(ARGSZ * SZREG)
53         .fmask  0x00000000, 0
55 #ifdef __PIC__
56         SETUP_GP
57 #endif
59         PTR_ADDIU sp, -FRAMESZ
60         cfi_adjust_cfa_offset (FRAMESZ)
62 #ifdef __PIC__
63         SETUP_GP64_STACK (GPOFF, __setcontext)
64         SAVE_GP (GPOFF)
65 #endif
67 #ifdef PROF
68         .set    noat
69         move    AT, ra
70         jal     _mcount
71         .set    at
72 #endif
74         /* Check for the magic flag.  */
75         li      v0, 1
76         REG_L   v1, (0 * SZREG + MCONTEXT_GREGS)(a0)    /* zero */
77         bne     v0, v1, 98f
79         REG_S   a0, A0OFF(sp)
81 /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */
82         li      a3, _NSIG8
83         move    a2, zero
84         PTR_ADDU a1, a0, UCONTEXT_SIGMASK
85         li      a0, SIG_SETMASK
87         li      v0, SYS_ify (rt_sigprocmask)
88         syscall
89         bnez    a3, 99f
91         REG_L   v0, A0OFF(sp)
93 #ifdef __mips_hard_float
94 # if _MIPS_SIM == _ABI64
95         l.d     fs0, (24 * SZREG + MCONTEXT_FPREGS)(v0)
96         l.d     fs1, (25 * SZREG + MCONTEXT_FPREGS)(v0)
97         l.d     fs2, (26 * SZREG + MCONTEXT_FPREGS)(v0)
98         l.d     fs3, (27 * SZREG + MCONTEXT_FPREGS)(v0)
99         l.d     fs4, (28 * SZREG + MCONTEXT_FPREGS)(v0)
100         l.d     fs5, (29 * SZREG + MCONTEXT_FPREGS)(v0)
101         l.d     fs6, (30 * SZREG + MCONTEXT_FPREGS)(v0)
102         l.d     fs7, (31 * SZREG + MCONTEXT_FPREGS)(v0)
104 # else  /* _MIPS_SIM != _ABI64 */
105         l.d     fs0, (20 * SZREG + MCONTEXT_FPREGS)(v0)
106         l.d     fs1, (22 * SZREG + MCONTEXT_FPREGS)(v0)
107         l.d     fs2, (24 * SZREG + MCONTEXT_FPREGS)(v0)
108         l.d     fs3, (26 * SZREG + MCONTEXT_FPREGS)(v0)
109         l.d     fs4, (28 * SZREG + MCONTEXT_FPREGS)(v0)
110         l.d     fs5, (30 * SZREG + MCONTEXT_FPREGS)(v0)
112 # endif /* _MIPS_SIM != _ABI64 */
114         lw      v1, MCONTEXT_FPC_CSR(v0)
115         ctc1    v1, fcr31
116 #endif /* __mips_hard_float */
118         /* Note the contents of argument registers will be random
119            unless makecontext() has been called.  */
120         REG_L   a0, (4 * SZREG + MCONTEXT_GREGS)(v0)
121         REG_L   a1, (5 * SZREG + MCONTEXT_GREGS)(v0)
122         REG_L   a2, (6 * SZREG + MCONTEXT_GREGS)(v0)
123         REG_L   a3, (7 * SZREG + MCONTEXT_GREGS)(v0)
124 #if _MIPS_SIM != _ABIO32
125         REG_L   a4, (8 * SZREG + MCONTEXT_GREGS)(v0)
126         REG_L   a5, (9 * SZREG + MCONTEXT_GREGS)(v0)
127         REG_L   a6, (10 * SZREG + MCONTEXT_GREGS)(v0)
128         REG_L   a7, (11 * SZREG + MCONTEXT_GREGS)(v0)
129 #endif
131         REG_L   s0, (16 * SZREG + MCONTEXT_GREGS)(v0)
132         REG_L   s1, (17 * SZREG + MCONTEXT_GREGS)(v0)
133         REG_L   s2, (18 * SZREG + MCONTEXT_GREGS)(v0)
134         REG_L   s3, (19 * SZREG + MCONTEXT_GREGS)(v0)
135         REG_L   s4, (20 * SZREG + MCONTEXT_GREGS)(v0)
136         REG_L   s5, (21 * SZREG + MCONTEXT_GREGS)(v0)
137         REG_L   s6, (22 * SZREG + MCONTEXT_GREGS)(v0)
138         REG_L   s7, (23 * SZREG + MCONTEXT_GREGS)(v0)
139 #if ! defined (__PIC__) || _MIPS_SIM != _ABIO32
140         REG_L   gp, (28 * SZREG + MCONTEXT_GREGS)(v0)
141 #endif
142         REG_L   sp, (29 * SZREG + MCONTEXT_GREGS)(v0)
143         REG_L   fp, (30 * SZREG + MCONTEXT_GREGS)(v0)
144         REG_L   ra, (31 * SZREG + MCONTEXT_GREGS)(v0)
145         REG_L   t9, MCONTEXT_PC(v0)
147         move    v0, zero
148         jr      t9
151         /* This is a context obtained from a signal handler.
152            Perform a full restore by pushing the context
153            passed onto a simulated signal frame on the stack
154            and call the signal return syscall as if a signal
155            handler exited normally.  */
156         PTR_ADDIU sp, -((RT_SIGFRAME_SIZE + ALSZ) & ALMASK)
157         cfi_adjust_cfa_offset ((RT_SIGFRAME_SIZE + ALSZ) & ALMASK)
159         /* Only ucontext is referred to from rt_sigreturn,
160            copy it.  */
161         PTR_ADDIU t1, sp, RT_SIGFRAME_UCONTEXT
162         li      t3, ((UCONTEXT_SIZE + SZREG - 1) / SZREG) - 1
164         REG_L   t2, (a0)
165         PTR_ADDIU a0, SZREG
166         REG_S   t2, (t1)
167         PTR_ADDIU t1, SZREG
168         .set    noreorder
169         bgtz    t3, 0b
170          addiu  t3, -1
171         .set    reorder
173 /* rt_sigreturn () -- no arguments, sp points to struct rt_sigframe.  */
174         li      v0, SYS_ify (rt_sigreturn)
175         syscall
177         /* Restore the stack and fall through to the error
178            path.  Successful rt_sigreturn never returns to
179            its calling place.  */
180         PTR_ADDIU sp, ((RT_SIGFRAME_SIZE + ALSZ) & ALMASK)
181         cfi_adjust_cfa_offset (-((RT_SIGFRAME_SIZE + ALSZ) & ALMASK))
183 #ifdef __PIC__
184         PTR_LA  t9, JUMPTARGET (__syscall_error)
185         RESTORE_GP64_STACK
186         PTR_ADDIU sp, FRAMESZ
187         cfi_adjust_cfa_offset (-FRAMESZ)
188         jr      t9
190 #else  /* ! __PIC__ */
192         j       JUMPTARGET (__syscall_error)
193 #endif /* ! __PIC__ */
194 PSEUDO_END (__setcontext)
196 weak_alias (__setcontext, setcontext)