Move all files into ports/ subdirectory in preparation for merge with glibc
[glibc.git] / ports / sysdeps / unix / sysv / linux / mips / makecontext.S
blob6427339a66c2236a5d5ebb037a49a1c8a34355a8
1 /* Modify saved 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 makecontext (ucontext_t *ucp, (void *func) (), int argc, ...) */
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 = 5                                               /* save a3-a7 */
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 A3OFF = FRAMESZ - (5 * SZREG)                           /* callee-allocated */
46 A4OFF = FRAMESZ - (4 * SZREG)
47 A5OFF = FRAMESZ - (3 * SZREG)
48 A6OFF = FRAMESZ - (2 * SZREG)
49 A7OFF = FRAMESZ - (1 * SZREG)
50 NARGREGS = 8
51 #else
52 A3OFF = FRAMESZ + (3 * SZREG)                           /* caller-allocated */
53 NARGREGS = 4
54 #endif
56 NESTED (__makecontext, FRAMESZ, ra)
57         .mask   MASK, -(ARGSZ * SZREG)
58         .fmask  0x00000000, 0
60 98:
61 #ifdef __PIC__
62         SETUP_GP
63 #endif
65         PTR_ADDIU sp, -FRAMESZ
67 #ifdef __PIC__
68         SETUP_GP64 (GPOFF, __makecontext)
69         SAVE_GP (GPOFF)
70 #endif
72 #ifdef PROF
73         .set    noat
74         move    AT, ra
75         jal     _mcount
76         .set    at
77 #endif
79         /* Store args to be passed.  */
80         REG_S   a3, A3OFF(sp)
81 #if _MIPS_SIM != _ABIO32
82         REG_S   a4, A4OFF(sp)
83         REG_S   a5, A5OFF(sp)
84         REG_S   a6, A6OFF(sp)
85         REG_S   a7, A7OFF(sp)
86 #endif
88         /* Store a magic flag.  */
89         li      v1, 1
90         REG_S   v1, (0 * SZREG + MCONTEXT_GREGS)(a0)    /* zero */
92         /* Set up the stack.  */
93         PTR_L   t0, STACK_SP(a0)
94         PTR_L   t2, STACK_SIZE(a0)
95         PTR_ADDIU t1, sp, A3OFF
96         PTR_ADDU t0, t2
97         and     t0, ALMASK
98         blez    a2, 2f                                  /* no arguments */
100         /* Store register arguments.  */
101         PTR_ADDIU t2, a0, MCONTEXT_GREGS + 4 * SZREG
102         move    t3, zero
104         addiu   t3, 1
105         REG_L   v1, (t1)
106         PTR_ADDIU t1, SZREG
107         REG_S   v1, (t2)
108         PTR_ADDIU t2, SZREG
109         bgeu    t3, a2, 2f                              /* all done */
110         bltu    t3, NARGREGS, 0b                        /* next */
112         /* Make room for stack arguments.  */
113         PTR_SUBU t2, a2, t3
114         PTR_SLL t2, 3
115         PTR_SUBU t0, t2
116         and     t0, ALMASK
118         /* Store stack arguments.  */
119         move    t2, t0
121         addiu   t3, 1
122         REG_L   v1, (t1)
123         PTR_ADDIU t1, SZREG
124         REG_S   v1, (t2)
125         PTR_ADDIU t2, SZREG
126         bltu    t3, a2, 1b                              /* next */
129 #if _MIPS_SIM == _ABIO32
130         /* Make room for a0-a3 storage.  */
131         PTR_ADDIU t0, -(NARGSAVE * SZREG)
132 #endif
133         PTR_L   v1, UCONTEXT_LINK(a0)
134 #ifdef __PIC__
135         PTR_ADDIU t9, 99f - 98b
136 #else
137         PTR_LA  t9, 99f
138 #endif
139         REG_S   t0, (29 * SZREG + MCONTEXT_GREGS)(a0)   /* sp */
140         REG_S   v1, (16 * SZREG + MCONTEXT_GREGS)(a0)   /* s0 */
141 #ifdef __PIC__
142         REG_S   gp, (17 * SZREG + MCONTEXT_GREGS)(a0)   /* s1 */
143 #endif
144         REG_S   t9, (31 * SZREG + MCONTEXT_GREGS)(a0)   /* ra */
145         REG_S   a1, MCONTEXT_PC(a0)
147 #ifdef __PIC__
148         RESTORE_GP64
149         PTR_ADDIU sp, FRAMESZ
150 #endif
151         jr      ra
154 #ifdef __PIC__
155         move    gp, s1
156 #endif
157         move    a0, zero
158         beqz    s0, 0f
160         /* setcontext (ucp) */
161         move    a0, s0
162 #ifdef __PIC__
163         PTR_LA  t9, JUMPTARGET (__setcontext)
164         jalr    t9
165 # if _MIPS_SIM == _ABIO32
166         move    gp, s1
167 # endif
168 #else
169         jal     JUMPTARGET (__setcontext)
170 #endif
171         move    a0, v0
174         /* exit (a0) */
175 #ifdef __PIC__
176         PTR_LA  t9, HIDDEN_JUMPTARGET (exit)
177         jalr    t9
178 #else
179         jal     HIDDEN_JUMPTARGET (exit)
180 #endif
182         /* You don't exist, you won't feel anything.  */
184         lb      zero, (zero)
185         b       1b
186 PSEUDO_END (__makecontext)
188 weak_alias (__makecontext, makecontext)