]>
Commit | Line | Data |
---|---|---|
568035b7 | 1 | /* Copyright (C) 2004-2013 Free Software Foundation, Inc. |
4dbd216d RH |
2 | This file is part of the GNU C Library. |
3 | ||
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. | |
8 | ||
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. | |
13 | ||
14 | You should have received a copy of the GNU Lesser General Public | |
ab84e3ff PE |
15 | License along with the GNU C Library. If not, see |
16 | <http://www.gnu.org/licenses/>. */ | |
4dbd216d RH |
17 | |
18 | #include <sysdep.h> | |
19 | #include <ucontext-offsets.h> | |
20 | ||
21 | ||
22 | ENTRY(__makecontext) | |
23 | ldgp $29, 0($27) | |
24 | #ifdef PROF | |
25 | .set noat | |
26 | lda AT, _mcount | |
27 | jsr AT, (AT), _mcount | |
28 | .set at | |
29 | #endif | |
30 | .prologue 1 | |
31 | ||
32 | /* Compute top of stack, including arguments. */ | |
33 | ldq $1, UC_STACK+SS_SP($16) | |
34 | ldq $2, UC_STACK+SS_SIZE($16) | |
35 | addq $1, $2, $8 | |
36 | subq $18, 6, $1 | |
37 | cmovlt $1, 0, $1 | |
38 | s8addq $1, 0, $2 | |
39 | subq $8, $2, $8 | |
40 | ||
41 | /* Copy all parameters. Switch statement header here. */ | |
42 | ldah $3, $jumptable($29) !gprelhigh | |
43 | cmple $18, 6, $1 | |
44 | mov $18, $2 | |
45 | cmoveq $1, 7, $2 | |
46 | s4addq $2, $3, $3 | |
47 | ldl $4, $jumptable($3) !gprellow | |
48 | addq $4, $29, $4 | |
49 | jmp $31, ($4), $args1 | |
50 | ||
51 | .section .rodata | |
52 | .align 2 | |
53 | $jumptable: | |
54 | .gprel32 $args0 | |
55 | .gprel32 $args1 | |
56 | .gprel32 $args2 | |
57 | .gprel32 $args3 | |
58 | .gprel32 $args4 | |
59 | .gprel32 $args5 | |
60 | .gprel32 $args6 | |
61 | .gprel32 $argsN | |
62 | .text | |
63 | ||
64 | /* Here we process arguments 7 through N. This is a straight | |
65 | stack-to-stack copy. */ | |
66 | .align 4 | |
67 | $argsN: | |
68 | subq $18, 6, $1 | |
69 | lda $2, 0($8) | |
70 | lda $3, 3*8($30) | |
71 | .align 4 | |
72 | 1: | |
73 | ldq $0, 0($3) | |
74 | subq $1, 1, $1 | |
75 | lda $3, 8($3) | |
76 | stq $0, 0($2) | |
77 | lda $2, 8($2) | |
78 | bne $1, 1b | |
79 | ||
80 | /* Here we process arguments 6 through 0. This involves | |
81 | copying into the register save areas of the ucontext. */ | |
82 | .align 4 | |
83 | $args6: | |
84 | ldq $0, 2*8($30) | |
85 | stq $0, UC_SIGCTX+SC_REGS+21*8($16) | |
86 | unop | |
87 | stq $0, UC_SIGCTX+SC_FPREGS+21*8($16) | |
88 | $args5: | |
89 | ldq $0, 1*8($30) | |
90 | stq $0, UC_SIGCTX+SC_REGS+20*8($16) | |
91 | unop | |
92 | stq $0, UC_SIGCTX+SC_FPREGS+20*8($16) | |
93 | $args4: | |
94 | ldq $0, 0*8($30) | |
95 | stq $0, UC_SIGCTX+SC_REGS+19*8($16) | |
96 | unop | |
97 | stq $0, UC_SIGCTX+SC_FPREGS+19*8($16) | |
98 | $args3: | |
99 | unop | |
100 | stq $21, UC_SIGCTX+SC_REGS+18*8($16) | |
101 | unop | |
102 | stt $f21, UC_SIGCTX+SC_FPREGS+18*8($16) | |
103 | $args2: | |
104 | unop | |
105 | stq $20, UC_SIGCTX+SC_REGS+17*8($16) | |
106 | unop | |
107 | stt $f20, UC_SIGCTX+SC_FPREGS+17*8($16) | |
108 | $args1: | |
109 | unop | |
110 | stq $19, UC_SIGCTX+SC_REGS+16*8($16) | |
111 | unop | |
112 | stt $f19, UC_SIGCTX+SC_FPREGS+16*8($16) | |
113 | $args0: | |
114 | ||
115 | /* Set up the registers ready to invoke __startcontext. | |
116 | We seed $27 with the target function address, and $9 | |
117 | with the link from ucp. */ | |
118 | ldah $0, __startcontext($29) !gprelhigh | |
119 | ldq $1, UC_LINK($16) | |
120 | lda $0, __startcontext($0) !gprellow | |
121 | stq $17, UC_SIGCTX+SC_REGS+27*8($16) | |
122 | stq $8, UC_SIGCTX+SC_REGS+30*8($16) | |
123 | stq $0, UC_SIGCTX+SC_PC($16) | |
124 | stq $1, UC_SIGCTX+SC_REGS+9*8($16) | |
125 | ||
126 | /* No return value from makecontext. */ | |
127 | ret | |
128 | ||
129 | END(__makecontext) | |
130 | weak_alias (__makecontext, makecontext) | |
131 | ||
132 | /* This function is where a new makecontext "thread" begins life. | |
133 | We have already set up $27 for calling the target function, and | |
134 | we've set $9 to the UC_LINK of the parent context. | |
135 | ||
136 | If the function returns, we either jump to the linked context | |
137 | (if non-null) or exit. */ | |
138 | ||
139 | .align 4 | |
140 | .ent __startcontext | |
141 | __startcontext: | |
142 | .frame $31, 0, $31, 0 | |
143 | .prologue 0 | |
144 | ||
145 | jsr $26, ($27), 0 | |
146 | ldgp $29, 0($26) | |
147 | mov $9, $16 | |
148 | beq $9, 1f | |
149 | ||
150 | #ifdef PIC | |
151 | bsr $26, __setcontext !samegp | |
152 | 1: mov $31, $16 | |
153 | bsr $26, HIDDEN_JUMPTARGET(exit) !samegp | |
154 | #else | |
155 | jsr $26, __setcontext | |
156 | ldgp $29, 0($26) | |
157 | 1: mov $31, $16 | |
158 | jsr $26, HIDDEN_JUMPTARGET(exit) | |
159 | #endif | |
160 | ||
161 | halt | |
162 | ||
163 | .end __startcontext |