Update copyright dates with scripts/update-copyrights.
[glibc.git] / sysdeps / unix / sysv / linux / sh / makecontext.S
blob036d26f3fdf16fbd2c480ed751b7854ae1f80b67
1 /* Create new context.
2    Copyright (C) 2005-2015 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
20 #include <abort-instr.h>
22 #include "ucontext_i.h"
24 /* void __makecontext (struct ucontext *ucp, void (*func)(), int argc, ...);
25   __makecontext sets up a stack and registers for context to run a given
26   function.  The registers are set up like this:
27     r4-r7: parameters 1 to 4
28     r8   : uc_link from ucontext structure
29     pc   : (*func) pointer
30     pr   : address of exitcode
31     r15  : stack pointer for func.  */
33         .text
34         .align  5
35 ENTRY(__makecontext)
36         mov     #4, r3
37         mov.l   @(oSS_SP,r4), r1        /* r1 <- ucb->stack_base */
38         mov.l   @(oSS_SIZE,r4), r2      /* r2 <- ucb->stack_size */
39         add     r1, r2                  /* r2 <- stack_top */
40         cmp/gt  r3, r6                  /* argc > 4? */
41         bf/s    1f
42          shlr2  r2                      /* r2 <- stack_top / 4 */
43         sub     r6, r2
44         add     r3, r2
46         shll2   r2              /* r2 <- stack_top - ((argc > 4) ? 4 * (argc - 4) : 0 */
47         mov     #oR15, r0
48         mov.l   @(oLINK,r4), r1
49         mov.l   r2, @(r0,r4)    /* ucp->r15 <- r2 */
50         mov.l   r1, @(oR8,r4)   /* ucp->r8 <- ucp->uc_link */
51         mov     #oPC, r0
52         mov.l   r5, @(r0,r4)    /* ucp->PC <- func */
54         cmp/pl  r6              /* argc > 0? */
55         bf/s    .L1
56          dt     r6
57         mov.l   r7, @(oR4,r4)   /* ucp->r4 <- argv[0] */
58         cmp/pl  r6              /* argc > 1? */
59         bf/s    .L1
60          dt     r6
61         mov.l   @(0,r15), r1
62         mov.l   r1, @(oR5,r4)   /* ucp->r5 <- argv[1] */
63         cmp/pl  r6              /* argc > 2? */
64         bf/s    .L1
65          dt     r6
66         mov.l   @(4,r15), r1
67         mov.l   r1, @(oR6,r4)   /* ucp->r6 <- argv[2] */
68         cmp/pl  r6              /* argc > 3? */
69         bf/s    .L1
70          dt     r6
71         mov.l   @(8,r15), r1
72         mov.l   r1, @(oR7,r4)   /* ucp->r7 <- argv[3] */
73         mov     #12,r0
74 .L0:                            /* Save remaining argv[] on the stack.  */
75         cmp/pl  r6
76         bf/s    .L1
77          dt     r6
78         mov.l   @(r0,r15), r1
79         mov.l   r1, @r2
80         add     #4, r0
81         bra     .L0
82          add    #4, r2
83 .L1:
84 #ifdef PIC
85         mova    .Lexitcode, r0
86 #else
87         mov.l   .L2, r0
88 #endif
89         add     #oPR, r4
90         rts
91          mov.l  r0, @r4         /* ucp->pr <- exitcode */
92 #ifndef PIC
93         .align  2
94 .L2:
95         .long   .Lexitcode
96 #endif
97         cfi_endproc
99         .align  5
100         cfi_startproc
101 .Lexitcode:
102 #ifdef PIC
103         mov.l   r12, @-r15
104         cfi_adjust_cfa_offset (4)
105         cfi_rel_offset (r12, 0)
106         mova    .Lgot, r0
107         mov.l   .Lgot, r12
108         add     r0, r12
109 #endif
110         tst     r8, r8          /* ucb->uc_link == NULL? */
111         bt/s    2f
112          mov    r8, r4          /* r4 <- ucb->uc_link */
113         mov.l   .Lsetcontext, r1
114         sts.l   pr, @-r15
115         cfi_adjust_cfa_offset (4)
116         cfi_rel_offset (pr, 0)
117 #ifdef PIC
118         bsrf    r1
119 .LPCS0:
120          nop
121 #else
122         jsr     @r1
123          nop
124 #endif
125         /* Restore to keep CFI/CFA balanced.  */
126         lds.l   @r15+, pr
127         cfi_adjust_cfa_offset (-4)
128         cfi_restore (pr)
129         /* If this returns (which can happen if the syscall fails) we'll exit
130            the program with the return error value (-1).  */
131         mov     r0, r4
134         mov.l   .Lexit, r1
135 #ifdef PIC
136         add     r12, r1
137 #endif
138         jsr     @r1
139          nop
140         /* The 'exit' call should never return.  In case it does cause the
141            process to terminate.  */
142         ABORT_INSTRUCTION_ASM
144         .align  2
145 #ifdef PIC
146 .Lgot:
147         .long   _GLOBAL_OFFSET_TABLE_
148 .Lsetcontext:
149         .long   __setcontext@PLT-(.LPCS0+2-(.))
150 .Lexit:
151         .long   HIDDEN_JUMPTARGET(exit)@GOTOFF
152 #else
153 .Lsetcontext:
154         .long   __setcontext
155 .Lexit:
156         .long   HIDDEN_JUMPTARGET(exit)
157 #endif
158 PSEUDO_END(__makecontext)
160 weak_alias (__makecontext, makecontext)