1/* Save and 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>. 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#include <sys/asm.h> 22#include <sys/fpregdef.h> 23#include <sys/regdef.h> 24 25#include "ucontext_i.h" 26 27/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ 28 29 .text 30LOCALSZ = 0 31ARGSZ = 0 32MASK = 0x00000000 33#ifdef __PIC__ 34LOCALSZ = 1 /* save gp */ 35#endif 36#if _MIPS_SIM != _ABIO32 37ARGSZ = 1 /* save a1 */ 38# ifdef __PIC__ 39MASK = 0x10000000 40# endif 41#endif 42FRAMESZ = (((ARGSZ + LOCALSZ) * SZREG) + ALSZ) & ALMASK 43GPOFF = FRAMESZ - ((ARGSZ + 1) * SZREG) 44#if _MIPS_SIM != _ABIO32 45A1OFF = FRAMESZ - (1 * SZREG) /* callee-allocated */ 46#else 47A1OFF = FRAMESZ + (1 * SZREG) /* caller-allocated */ 48#endif 49 50NESTED (__swapcontext, FRAMESZ, ra) 51 .mask MASK, -(ARGSZ * SZREG) 52 .fmask 0x00000000, 0 53 54#ifdef __PIC__ 55 SETUP_GP 56 57 move a2, sp 58# define _SP a2 59 60# if _MIPS_SIM != _ABIO32 61 move a3, gp 62# define _GP a3 63# endif 64 65 PTR_ADDIU sp, -FRAMESZ 66 SETUP_GP64 (GPOFF, __swapcontext) 67 SAVE_GP (GPOFF) 68 69#else /* ! __PIC__ */ 70# define _SP sp 71# define _GP gp 72 73#endif /* ! __PIC__ */ 74 75 /* Store a magic flag. */ 76 li v1, 1 77 REG_S v1, (0 * SZREG + MCONTEXT_GREGS)(a0) /* zero */ 78 79 REG_S s0, (16 * SZREG + MCONTEXT_GREGS)(a0) 80 REG_S s1, (17 * SZREG + MCONTEXT_GREGS)(a0) 81 REG_S s2, (18 * SZREG + MCONTEXT_GREGS)(a0) 82 REG_S s3, (19 * SZREG + MCONTEXT_GREGS)(a0) 83 REG_S s4, (20 * SZREG + MCONTEXT_GREGS)(a0) 84 REG_S s5, (21 * SZREG + MCONTEXT_GREGS)(a0) 85 REG_S s6, (22 * SZREG + MCONTEXT_GREGS)(a0) 86 REG_S s7, (23 * SZREG + MCONTEXT_GREGS)(a0) 87#if ! defined (__PIC__) || _MIPS_SIM != _ABIO32 88 REG_S _GP, (28 * SZREG + MCONTEXT_GREGS)(a0) 89#endif 90 REG_S _SP, (29 * SZREG + MCONTEXT_GREGS)(a0) 91 REG_S fp, (30 * SZREG + MCONTEXT_GREGS)(a0) 92 REG_S ra, (31 * SZREG + MCONTEXT_GREGS)(a0) 93 REG_S ra, MCONTEXT_PC(a0) 94 95#ifdef __mips_hard_float 96# if _MIPS_SIM == _ABI64 97 s.d fs0, (24 * SZREG + MCONTEXT_FPREGS)(a0) 98 s.d fs1, (25 * SZREG + MCONTEXT_FPREGS)(a0) 99 s.d fs2, (26 * SZREG + MCONTEXT_FPREGS)(a0) 100 s.d fs3, (27 * SZREG + MCONTEXT_FPREGS)(a0) 101 s.d fs4, (28 * SZREG + MCONTEXT_FPREGS)(a0) 102 s.d fs5, (29 * SZREG + MCONTEXT_FPREGS)(a0) 103 s.d fs6, (30 * SZREG + MCONTEXT_FPREGS)(a0) 104 s.d fs7, (31 * SZREG + MCONTEXT_FPREGS)(a0) 105 106# else /* _MIPS_SIM != _ABI64 */ 107 s.d fs0, (20 * SZREG + MCONTEXT_FPREGS)(a0) 108 s.d fs1, (22 * SZREG + MCONTEXT_FPREGS)(a0) 109 s.d fs2, (24 * SZREG + MCONTEXT_FPREGS)(a0) 110 s.d fs3, (26 * SZREG + MCONTEXT_FPREGS)(a0) 111 s.d fs4, (28 * SZREG + MCONTEXT_FPREGS)(a0) 112 s.d fs5, (30 * SZREG + MCONTEXT_FPREGS)(a0) 113 114# endif /* _MIPS_SIM != _ABI64 */ 115 116 cfc1 v1, fcr31 117 sw v1, MCONTEXT_FPC_CSR(a0) 118#endif /* __mips_hard_float */ 119 120 REG_S a1, A1OFF(sp) 121 122/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */ 123 li a3, _NSIG8 124 PTR_ADDU a2, a0, UCONTEXT_SIGMASK 125 PTR_ADDU a1, a1, UCONTEXT_SIGMASK 126 li a0, SIG_SETMASK 127 128 li v0, SYS_ify (rt_sigprocmask) 129 syscall 130 bnez a3, 99f 131 132 REG_L v0, A1OFF(sp) 133 134#ifdef __mips_hard_float 135# if _MIPS_SIM == _ABI64 136 l.d fs0, (24 * SZREG + MCONTEXT_FPREGS)(v0) 137 l.d fs1, (25 * SZREG + MCONTEXT_FPREGS)(v0) 138 l.d fs2, (26 * SZREG + MCONTEXT_FPREGS)(v0) 139 l.d fs3, (27 * SZREG + MCONTEXT_FPREGS)(v0) 140 l.d fs4, (28 * SZREG + MCONTEXT_FPREGS)(v0) 141 l.d fs5, (29 * SZREG + MCONTEXT_FPREGS)(v0) 142 l.d fs6, (30 * SZREG + MCONTEXT_FPREGS)(v0) 143 l.d fs7, (31 * SZREG + MCONTEXT_FPREGS)(v0) 144 145# else /* _MIPS_SIM != _ABI64 */ 146 l.d fs0, (20 * SZREG + MCONTEXT_FPREGS)(v0) 147 l.d fs1, (22 * SZREG + MCONTEXT_FPREGS)(v0) 148 l.d fs2, (24 * SZREG + MCONTEXT_FPREGS)(v0) 149 l.d fs3, (26 * SZREG + MCONTEXT_FPREGS)(v0) 150 l.d fs4, (28 * SZREG + MCONTEXT_FPREGS)(v0) 151 l.d fs5, (30 * SZREG + MCONTEXT_FPREGS)(v0) 152 153# endif /* _MIPS_SIM != _ABI64 */ 154 155 lw v1, MCONTEXT_FPC_CSR(v0) 156 ctc1 v1, fcr31 157#endif /* __mips_hard_float */ 158 159 /* Note the contents of argument registers will be random 160 unless makecontext() has been called. */ 161 REG_L a0, (4 * SZREG + MCONTEXT_GREGS)(v0) 162 REG_L a1, (5 * SZREG + MCONTEXT_GREGS)(v0) 163 REG_L a2, (6 * SZREG + MCONTEXT_GREGS)(v0) 164 REG_L a3, (7 * SZREG + MCONTEXT_GREGS)(v0) 165#if _MIPS_SIM != _ABIO32 166 REG_L a4, (8 * SZREG + MCONTEXT_GREGS)(v0) 167 REG_L a5, (9 * SZREG + MCONTEXT_GREGS)(v0) 168 REG_L a6, (10 * SZREG + MCONTEXT_GREGS)(v0) 169 REG_L a7, (11 * SZREG + MCONTEXT_GREGS)(v0) 170#endif 171 172 REG_L s0, (16 * SZREG + MCONTEXT_GREGS)(v0) 173 REG_L s1, (17 * SZREG + MCONTEXT_GREGS)(v0) 174 REG_L s2, (18 * SZREG + MCONTEXT_GREGS)(v0) 175 REG_L s3, (19 * SZREG + MCONTEXT_GREGS)(v0) 176 REG_L s4, (20 * SZREG + MCONTEXT_GREGS)(v0) 177 REG_L s5, (21 * SZREG + MCONTEXT_GREGS)(v0) 178 REG_L s6, (22 * SZREG + MCONTEXT_GREGS)(v0) 179 REG_L s7, (23 * SZREG + MCONTEXT_GREGS)(v0) 180#if ! defined (__PIC__) || _MIPS_SIM != _ABIO32 181 REG_L gp, (28 * SZREG + MCONTEXT_GREGS)(v0) 182#endif 183 REG_L sp, (29 * SZREG + MCONTEXT_GREGS)(v0) 184 REG_L fp, (30 * SZREG + MCONTEXT_GREGS)(v0) 185 REG_L ra, (31 * SZREG + MCONTEXT_GREGS)(v0) 186 REG_L t9, MCONTEXT_PC(v0) 187 188 move v0, zero 189 jr t9 190 19199: 192#ifdef __PIC__ 193 PTR_LA t9, JUMPTARGET (__syscall_error) 194 RESTORE_GP64 195 PTR_ADDIU sp, FRAMESZ 196 jr t9 197 198#else /* ! __PIC__ */ 199 200 j JUMPTARGET (__syscall_error) 201#endif /* ! __PIC__ */ 202PSEUDO_END (__swapcontext) 203 204weak_alias (__swapcontext, swapcontext) 205