1 | /* Copyright (C) 2004-2022 Free Software Foundation, Inc. |
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 |
15 | License along with the GNU C Library. If not, see |
16 | <https://www.gnu.org/licenses/>. */ |
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 |
164 | |