]>
Commit | Line | Data |
---|---|---|
ff347533 | 1 | /* Modify saved context. |
04277e02 | 2 | Copyright (C) 2009-2019 Free Software Foundation, Inc. |
ff347533 JM |
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 | |
ab84e3ff | 17 | License along with the GNU C Library. If not, see |
5a82c748 | 18 | <https://www.gnu.org/licenses/>. */ |
ff347533 JM |
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 makecontext (ucontext_t *ucp, (void *func) (), int argc, ...) */ | |
28 | ||
29 | .text | |
43301bd3 | 30 | .set nomips16 |
ff347533 JM |
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 = 5 /* save a3-a7 */ | |
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 | A3OFF = FRAMESZ - (5 * SZREG) /* callee-allocated */ | |
47 | A4OFF = FRAMESZ - (4 * SZREG) | |
48 | A5OFF = FRAMESZ - (3 * SZREG) | |
49 | A6OFF = FRAMESZ - (2 * SZREG) | |
50 | A7OFF = FRAMESZ - (1 * SZREG) | |
51 | NARGREGS = 8 | |
52 | #else | |
53 | A3OFF = FRAMESZ + (3 * SZREG) /* caller-allocated */ | |
54 | NARGREGS = 4 | |
55 | #endif | |
b309f058 GC |
56 | MCONTEXT_GREGSZ = 8 |
57 | #if _MIPS_SIM == _ABIO32 && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | |
58 | MCONTEXT_GREGOFF = 4 | |
59 | #else | |
60 | MCONTEXT_GREGOFF = 0 | |
61 | #endif | |
ff347533 JM |
62 | |
63 | NESTED (__makecontext, FRAMESZ, ra) | |
64 | .mask MASK, -(ARGSZ * SZREG) | |
65 | .fmask 0x00000000, 0 | |
66 | ||
67 | 98: | |
68 | #ifdef __PIC__ | |
69 | SETUP_GP | |
70 | #endif | |
71 | ||
72 | PTR_ADDIU sp, -FRAMESZ | |
aea7a9b9 | 73 | cfi_adjust_cfa_offset (FRAMESZ) |
ff347533 JM |
74 | |
75 | #ifdef __PIC__ | |
aea7a9b9 | 76 | SETUP_GP64_STACK (GPOFF, __makecontext) |
ff347533 JM |
77 | SAVE_GP (GPOFF) |
78 | #endif | |
79 | ||
80 | #ifdef PROF | |
81 | .set noat | |
82 | move AT, ra | |
83 | jal _mcount | |
84 | .set at | |
85 | #endif | |
86 | ||
87 | /* Store args to be passed. */ | |
88 | REG_S a3, A3OFF(sp) | |
89 | #if _MIPS_SIM != _ABIO32 | |
90 | REG_S a4, A4OFF(sp) | |
91 | REG_S a5, A5OFF(sp) | |
92 | REG_S a6, A6OFF(sp) | |
93 | REG_S a7, A7OFF(sp) | |
94 | #endif | |
95 | ||
ff347533 JM |
96 | /* Set up the stack. */ |
97 | PTR_L t0, STACK_SP(a0) | |
98 | PTR_L t2, STACK_SIZE(a0) | |
99 | PTR_ADDIU t1, sp, A3OFF | |
100 | PTR_ADDU t0, t2 | |
101 | and t0, ALMASK | |
102 | blez a2, 2f /* no arguments */ | |
103 | ||
104 | /* Store register arguments. */ | |
b309f058 | 105 | PTR_ADDIU t2, a0, MCONTEXT_GREGS + 4 * MCONTEXT_GREGSZ + MCONTEXT_GREGOFF |
ff347533 JM |
106 | move t3, zero |
107 | 0: | |
108 | addiu t3, 1 | |
109 | REG_L v1, (t1) | |
110 | PTR_ADDIU t1, SZREG | |
111 | REG_S v1, (t2) | |
b309f058 | 112 | PTR_ADDIU t2, MCONTEXT_GREGSZ |
ff347533 JM |
113 | bgeu t3, a2, 2f /* all done */ |
114 | bltu t3, NARGREGS, 0b /* next */ | |
115 | ||
116 | /* Make room for stack arguments. */ | |
117 | PTR_SUBU t2, a2, t3 | |
118 | PTR_SLL t2, 3 | |
119 | PTR_SUBU t0, t2 | |
120 | and t0, ALMASK | |
121 | ||
122 | /* Store stack arguments. */ | |
123 | move t2, t0 | |
124 | 1: | |
125 | addiu t3, 1 | |
126 | REG_L v1, (t1) | |
127 | PTR_ADDIU t1, SZREG | |
128 | REG_S v1, (t2) | |
129 | PTR_ADDIU t2, SZREG | |
130 | bltu t3, a2, 1b /* next */ | |
131 | ||
132 | 2: | |
133 | #if _MIPS_SIM == _ABIO32 | |
134 | /* Make room for a0-a3 storage. */ | |
135 | PTR_ADDIU t0, -(NARGSAVE * SZREG) | |
136 | #endif | |
137 | PTR_L v1, UCONTEXT_LINK(a0) | |
138 | #ifdef __PIC__ | |
139 | PTR_ADDIU t9, 99f - 98b | |
140 | #else | |
141 | PTR_LA t9, 99f | |
142 | #endif | |
b309f058 GC |
143 | /* sp */ |
144 | REG_S t0, (MCONTEXT_GREGOFF + 29 * MCONTEXT_GREGSZ + MCONTEXT_GREGS)(a0) | |
145 | /* s0 */ | |
146 | REG_S v1, (MCONTEXT_GREGOFF + 16 * MCONTEXT_GREGSZ + MCONTEXT_GREGS)(a0) | |
ff347533 | 147 | #ifdef __PIC__ |
b309f058 GC |
148 | /* s1 */ |
149 | REG_S gp, (MCONTEXT_GREGOFF + 17 * MCONTEXT_GREGSZ + MCONTEXT_GREGS)(a0) | |
ff347533 | 150 | #endif |
b309f058 GC |
151 | /* ra */ |
152 | REG_S t9, (MCONTEXT_GREGOFF + 31 * MCONTEXT_GREGSZ + MCONTEXT_GREGS)(a0) | |
153 | REG_S a1, (MCONTEXT_GREGOFF + MCONTEXT_PC)(a0) | |
ff347533 JM |
154 | |
155 | #ifdef __PIC__ | |
aea7a9b9 | 156 | RESTORE_GP64_STACK |
ff347533 | 157 | PTR_ADDIU sp, FRAMESZ |
aea7a9b9 | 158 | cfi_adjust_cfa_offset (-FRAMESZ) |
ff347533 JM |
159 | #endif |
160 | jr ra | |
161 | ||
f8e9c4d3 AJ |
162 | /* We need to terminate the FDE to stop unwinding if backtrace was |
163 | called within a context created by makecontext. */ | |
164 | cfi_endproc | |
165 | nop | |
166 | ||
ff347533 JM |
167 | 99: |
168 | #ifdef __PIC__ | |
169 | move gp, s1 | |
170 | #endif | |
171 | move a0, zero | |
172 | beqz s0, 0f | |
173 | ||
174 | /* setcontext (ucp) */ | |
175 | move a0, s0 | |
176 | #ifdef __PIC__ | |
177 | PTR_LA t9, JUMPTARGET (__setcontext) | |
178 | jalr t9 | |
179 | # if _MIPS_SIM == _ABIO32 | |
180 | move gp, s1 | |
181 | # endif | |
182 | #else | |
183 | jal JUMPTARGET (__setcontext) | |
184 | #endif | |
185 | move a0, v0 | |
186 | ||
187 | 0: | |
188 | /* exit (a0) */ | |
189 | #ifdef __PIC__ | |
190 | PTR_LA t9, HIDDEN_JUMPTARGET (exit) | |
191 | jalr t9 | |
192 | #else | |
193 | jal HIDDEN_JUMPTARGET (exit) | |
194 | #endif | |
195 | ||
196 | /* You don't exist, you won't feel anything. */ | |
197 | 1: | |
198 | lb zero, (zero) | |
199 | b 1b | |
f8e9c4d3 AJ |
200 | |
201 | cfi_startproc | |
ff347533 JM |
202 | PSEUDO_END (__makecontext) |
203 | ||
204 | weak_alias (__makecontext, makecontext) |