Move all files into ports/ subdirectory in preparation for merge with glibc
[glibc.git] / ports / sysdeps / unix / sysv / linux / mips / setcontext.S
blobd3cde0e504b46f85b2ddb00fb46885505b10004d
1 /* Set current context.
2    Copyright (C) 2009 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 LOCALSZ = 0
31 ARGSZ = 0
32 MASK = 0x00000000
33 #ifdef __PIC__
34 LOCALSZ = 1                                             /* save gp */
35 #endif
36 #if _MIPS_SIM != _ABIO32
37 ARGSZ = 1                                               /* save a0 */
38 # ifdef __PIC__
39 MASK = 0x10000000
40 # endif
41 #endif
42 FRAMESZ = (((ARGSZ + LOCALSZ) * SZREG) + ALSZ) & ALMASK
43 GPOFF = FRAMESZ - ((ARGSZ + 1) * SZREG)
44 #if _MIPS_SIM != _ABIO32
45 A0OFF = FRAMESZ - (1 * SZREG)                           /* callee-allocated */
46 #else
47 A0OFF = FRAMESZ + (0 * SZREG)                           /* caller-allocated */
48 #endif
50 NESTED (__setcontext, FRAMESZ, ra)
51         .mask   MASK, -(ARGSZ * SZREG)
52         .fmask  0x00000000, 0
54 #ifdef __PIC__
55         SETUP_GP
56 #endif
58         PTR_ADDIU sp, -FRAMESZ
60 #ifdef __PIC__
61         SETUP_GP64 (GPOFF, __setcontext)
62         SAVE_GP (GPOFF)
63 #endif
65 #ifdef PROF
66         .set    noat
67         move    AT, ra
68         jal     _mcount
69         .set    at
70 #endif
72         /* Check for the magic flag.  */
73         li      v0, 1
74         REG_L   v1, (0 * SZREG + MCONTEXT_GREGS)(a0)    /* zero */
75         bne     v0, v1, 98f
77         REG_S   a0, A0OFF(sp)
79 /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */
80         li      a3, _NSIG8
81         move    a2, zero
82         PTR_ADDU a1, a0, UCONTEXT_SIGMASK
83         li      a0, SIG_SETMASK
85         li      v0, SYS_ify (rt_sigprocmask)
86         syscall
87         bnez    a3, 99f
89         REG_L   v0, A0OFF(sp)
91 #ifdef __mips_hard_float
92 # if _MIPS_SIM == _ABI64
93         l.d     fs0, (24 * SZREG + MCONTEXT_FPREGS)(v0)
94         l.d     fs1, (25 * SZREG + MCONTEXT_FPREGS)(v0)
95         l.d     fs2, (26 * SZREG + MCONTEXT_FPREGS)(v0)
96         l.d     fs3, (27 * SZREG + MCONTEXT_FPREGS)(v0)
97         l.d     fs4, (28 * SZREG + MCONTEXT_FPREGS)(v0)
98         l.d     fs5, (29 * SZREG + MCONTEXT_FPREGS)(v0)
99         l.d     fs6, (30 * SZREG + MCONTEXT_FPREGS)(v0)
100         l.d     fs7, (31 * SZREG + MCONTEXT_FPREGS)(v0)
102 # else  /* _MIPS_SIM != _ABI64 */
103         l.d     fs0, (20 * SZREG + MCONTEXT_FPREGS)(v0)
104         l.d     fs1, (22 * SZREG + MCONTEXT_FPREGS)(v0)
105         l.d     fs2, (24 * SZREG + MCONTEXT_FPREGS)(v0)
106         l.d     fs3, (26 * SZREG + MCONTEXT_FPREGS)(v0)
107         l.d     fs4, (28 * SZREG + MCONTEXT_FPREGS)(v0)
108         l.d     fs5, (30 * SZREG + MCONTEXT_FPREGS)(v0)
110 # endif /* _MIPS_SIM != _ABI64 */
112         lw      v1, MCONTEXT_FPC_CSR(v0)
113         ctc1    v1, fcr31
114 #endif /* __mips_hard_float */
116         /* Note the contents of argument registers will be random
117            unless makecontext() has been called.  */
118         REG_L   a0, (4 * SZREG + MCONTEXT_GREGS)(v0)
119         REG_L   a1, (5 * SZREG + MCONTEXT_GREGS)(v0)
120         REG_L   a2, (6 * SZREG + MCONTEXT_GREGS)(v0)
121         REG_L   a3, (7 * SZREG + MCONTEXT_GREGS)(v0)
122 #if _MIPS_SIM != _ABIO32
123         REG_L   a4, (8 * SZREG + MCONTEXT_GREGS)(v0)
124         REG_L   a5, (9 * SZREG + MCONTEXT_GREGS)(v0)
125         REG_L   a6, (10 * SZREG + MCONTEXT_GREGS)(v0)
126         REG_L   a7, (11 * SZREG + MCONTEXT_GREGS)(v0)
127 #endif
129         REG_L   s0, (16 * SZREG + MCONTEXT_GREGS)(v0)
130         REG_L   s1, (17 * SZREG + MCONTEXT_GREGS)(v0)
131         REG_L   s2, (18 * SZREG + MCONTEXT_GREGS)(v0)
132         REG_L   s3, (19 * SZREG + MCONTEXT_GREGS)(v0)
133         REG_L   s4, (20 * SZREG + MCONTEXT_GREGS)(v0)
134         REG_L   s5, (21 * SZREG + MCONTEXT_GREGS)(v0)
135         REG_L   s6, (22 * SZREG + MCONTEXT_GREGS)(v0)
136         REG_L   s7, (23 * SZREG + MCONTEXT_GREGS)(v0)
137 #if ! defined (__PIC__) || _MIPS_SIM != _ABIO32
138         REG_L   gp, (28 * SZREG + MCONTEXT_GREGS)(v0)
139 #endif
140         REG_L   sp, (29 * SZREG + MCONTEXT_GREGS)(v0)
141         REG_L   fp, (30 * SZREG + MCONTEXT_GREGS)(v0)
142         REG_L   ra, (31 * SZREG + MCONTEXT_GREGS)(v0)
143         REG_L   t9, MCONTEXT_PC(v0)
145         move    v0, zero
146         jr      t9
149         /* This is a context obtained from a signal handler.
150            Perform a full restore by pushing the context
151            passed onto a simulated signal frame on the stack
152            and call the signal return syscall as if a signal
153            handler exited normally.  */
154         PTR_ADDIU sp, -((RT_SIGFRAME_SIZE + ALSZ) & ALMASK)
156         /* Only ucontext is referred to from rt_sigreturn,
157            copy it.  */
158         PTR_ADDIU t1, sp, RT_SIGFRAME_UCONTEXT
159         li      t3, ((UCONTEXT_SIZE + SZREG - 1) / SZREG) - 1
161         REG_L   t2, (a0)
162         PTR_ADDIU a0, SZREG
163         REG_S   t2, (t1)
164         PTR_ADDIU t1, SZREG
165         .set    noreorder
166         bgtz    t3, 0b
167          addiu  t3, -1
168         .set    reorder
170 /* rt_sigreturn () -- no arguments, sp points to struct rt_sigframe.  */
171         li      v0, SYS_ify (rt_sigreturn)
172         syscall
174         /* Restore the stack and fall through to the error
175            path.  Successful rt_sigreturn never returns to
176            its calling place.  */
177         PTR_ADDIU sp, ((RT_SIGFRAME_SIZE + ALSZ) & ALMASK)
179 #ifdef __PIC__
180         PTR_LA  t9, JUMPTARGET (__syscall_error)
181         RESTORE_GP64
182         PTR_ADDIU sp, FRAMESZ
183         jr      t9
185 #else  /* ! __PIC__ */
187         j       JUMPTARGET (__syscall_error)
188 #endif /* ! __PIC__ */
189 PSEUDO_END (__setcontext)
191 weak_alias (__setcontext, setcontext)