2.9
[glibc/nacl-glibc.git] / sysdeps / unix / sysv / linux / alpha / makecontext.S
blob223117e26da0e255d22eca419ff95ef0cc6b4f26
1 /* Copyright (C) 2004 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
19 #include <sysdep.h>
20 #include <ucontext-offsets.h>
23 ENTRY(__makecontext)
24         ldgp    $29, 0($27)
25 #ifdef PROF
26         .set noat
27         lda     AT, _mcount
28         jsr     AT, (AT), _mcount
29         .set at
30 #endif
31         .prologue 1
33         /* Compute top of stack, including arguments.  */
34         ldq     $1, UC_STACK+SS_SP($16)
35         ldq     $2, UC_STACK+SS_SIZE($16)
36         addq    $1, $2, $8
37         subq    $18, 6, $1
38         cmovlt  $1, 0, $1
39         s8addq  $1, 0, $2
40         subq    $8, $2, $8
42         /* Copy all parameters.  Switch statement header here.  */
43         ldah    $3, $jumptable($29)     !gprelhigh
44         cmple   $18, 6, $1
45         mov     $18, $2
46         cmoveq  $1, 7, $2
47         s4addq  $2, $3, $3
48         ldl     $4, $jumptable($3)      !gprellow
49         addq    $4, $29, $4
50         jmp     $31, ($4), $args1
52         .section .rodata
53         .align  2
54 $jumptable:
55         .gprel32  $args0
56         .gprel32  $args1
57         .gprel32  $args2
58         .gprel32  $args3
59         .gprel32  $args4
60         .gprel32  $args5
61         .gprel32  $args6
62         .gprel32  $argsN
63         .text
65         /* Here we process arguments 7 through N.  This is a straight
66            stack-to-stack copy.  */
67         .align  4
68 $argsN:
69         subq    $18, 6, $1
70         lda     $2, 0($8)
71         lda     $3, 3*8($30)
72         .align  4
74         ldq     $0, 0($3)
75         subq    $1, 1, $1
76         lda     $3, 8($3)
77         stq     $0, 0($2)
78         lda     $2, 8($2)
79         bne     $1, 1b
81         /* Here we process arguments 6 through 0.  This involves
82            copying into the register save areas of the ucontext.  */
83         .align  4
84 $args6:
85         ldq     $0, 2*8($30)
86         stq     $0, UC_SIGCTX+SC_REGS+21*8($16)
87         unop
88         stq     $0, UC_SIGCTX+SC_FPREGS+21*8($16)
89 $args5:
90         ldq     $0, 1*8($30)
91         stq     $0, UC_SIGCTX+SC_REGS+20*8($16)
92         unop
93         stq     $0, UC_SIGCTX+SC_FPREGS+20*8($16)
94 $args4:
95         ldq     $0, 0*8($30)
96         stq     $0, UC_SIGCTX+SC_REGS+19*8($16)
97         unop
98         stq     $0, UC_SIGCTX+SC_FPREGS+19*8($16)
99 $args3:
100         unop
101         stq     $21, UC_SIGCTX+SC_REGS+18*8($16)
102         unop
103         stt     $f21, UC_SIGCTX+SC_FPREGS+18*8($16)
104 $args2:
105         unop
106         stq     $20, UC_SIGCTX+SC_REGS+17*8($16)
107         unop
108         stt     $f20, UC_SIGCTX+SC_FPREGS+17*8($16)
109 $args1:
110         unop
111         stq     $19, UC_SIGCTX+SC_REGS+16*8($16)
112         unop
113         stt     $f19, UC_SIGCTX+SC_FPREGS+16*8($16)
114 $args0:
116         /* Set up the registers ready to invoke __startcontext.
117            We seed $27 with the target function address, and $9
118            with the link from ucp.  */
119         ldah    $0, __startcontext($29)         !gprelhigh
120         ldq     $1, UC_LINK($16)
121         lda     $0, __startcontext($0)          !gprellow
122         stq     $17, UC_SIGCTX+SC_REGS+27*8($16)
123         stq     $8, UC_SIGCTX+SC_REGS+30*8($16)
124         stq     $0, UC_SIGCTX+SC_PC($16)
125         stq     $1, UC_SIGCTX+SC_REGS+9*8($16)
127         /* No return value from makecontext.  */
128         ret
130 END(__makecontext)
131 weak_alias (__makecontext, makecontext)
133 /* This function is where a new makecontext "thread" begins life.
134    We have already set up $27 for calling the target function, and
135    we've set $9 to the UC_LINK of the parent context.
137    If the function returns, we either jump to the linked context
138    (if non-null) or exit.  */
140         .align  4
141         .ent    __startcontext
142 __startcontext:
143         .frame $31, 0, $31, 0
144         .prologue 0
146         jsr     $26, ($27), 0
147         ldgp    $29, 0($26)
148         mov     $9, $16
149         beq     $9, 1f
151 #ifdef PIC
152         bsr     $26, __setcontext               !samegp
153 1:      mov     $31, $16
154         bsr     $26, HIDDEN_JUMPTARGET(exit)    !samegp
155 #else
156         jsr     $26, __setcontext
157         ldgp    $29, 0($26)
158 1:      mov     $31, $16
159         jsr     $26, HIDDEN_JUMPTARGET(exit)
160 #endif
162         halt
164         .end __startcontext