KiCad PCB EDA Suite
libcontext.cpp
Go to the documentation of this file.
1 /*
2 
3  auto-generated file, do not modify!
4  libcontext - a slightly more portable version of boost::context
5  Copyright Martin Husemann 2013.
6  Copyright Oliver Kowalke 2009.
7  Copyright Sergue E. Leontiev 2013
8  Copyright Thomas Sailer 2013.
9  Minor modifications by Tomasz Wlostowski 2016.
10 
11  Distributed under the Boost Software License, Version 1.0.
12  (See accompanying file LICENSE.BOOSTv1_0.txt or copy at
13  http://www.boost.org/LICENSE_1_0.txt)
14 
15 */
16 #include <system/libcontext.h>
17 
18 #if defined(LIBCONTEXT_PLATFORM_windows_i386) && defined(LIBCONTEXT_COMPILER_gcc)
19 __asm (
20 ".text\n"
21 ".p2align 4,,15\n"
22 ".globl _jump_fcontext\n"
23 ".def _jump_fcontext; .scl 2; .type 32; .endef\n"
24 "_jump_fcontext:\n"
25 " mov 0x10(%esp),%ecx\n"
26 " push %ebp\n"
27 " push %ebx\n"
28 " push %esi\n"
29 " push %edi\n"
30 " mov %fs:0x18,%edx\n"
31 " mov (%edx),%eax\n"
32 " push %eax\n"
33 " mov 0x4(%edx),%eax\n"
34 " push %eax\n"
35 " mov 0x8(%edx),%eax\n"
36 " push %eax\n"
37 " mov 0xe0c(%edx),%eax\n"
38 " push %eax\n"
39 " mov 0x10(%edx),%eax\n"
40 " push %eax\n"
41 " lea -0x8(%esp),%esp\n"
42 " test %ecx,%ecx\n"
43 " je nxt1\n"
44 " stmxcsr (%esp)\n"
45 " fnstcw 0x4(%esp)\n"
46 "nxt1:\n"
47 " mov 0x30(%esp),%eax\n"
48 " mov %esp,(%eax)\n"
49 " mov 0x34(%esp),%edx\n"
50 " mov 0x38(%esp),%eax\n"
51 " mov %edx,%esp\n"
52 " test %ecx,%ecx\n"
53 " je nxt2\n"
54 " ldmxcsr (%esp)\n"
55 " fldcw 0x4(%esp)\n"
56 "nxt2:\n"
57 " lea 0x8(%esp),%esp\n"
58 " mov %fs:0x18,%edx\n"
59 " pop %ecx\n"
60 " mov %ecx,0x10(%edx)\n"
61 " pop %ecx\n"
62 " mov %ecx,0xe0c(%edx)\n"
63 " pop %ecx\n"
64 " mov %ecx,0x8(%edx)\n"
65 " pop %ecx\n"
66 " mov %ecx,0x4(%edx)\n"
67 " pop %ecx\n"
68 " mov %ecx,(%edx)\n"
69 " pop %edi\n"
70 " pop %esi\n"
71 " pop %ebx\n"
72 " pop %ebp\n"
73 " pop %edx\n"
74 " mov %eax,0x4(%esp)\n"
75 " jmp *%edx\n"
76 );
77 
78 #endif
79 
80 #if defined(LIBCONTEXT_PLATFORM_windows_i386) && defined(LIBCONTEXT_COMPILER_gcc)
81 __asm (
82 ".text\n"
83 ".p2align 4,,15\n"
84 ".globl _make_fcontext\n"
85 ".def _make_fcontext; .scl 2; .type 32; .endef\n"
86 "_make_fcontext:\n"
87 "mov 0x4(%esp),%eax\n"
88 "lea -0x8(%eax),%eax\n"
89 "and $0xfffffff0,%eax\n"
90 "lea -0x3c(%eax),%eax\n"
91 "mov 0x4(%esp),%ecx\n"
92 "mov %ecx,0x14(%eax)\n"
93 "mov 0x8(%esp),%edx\n"
94 "neg %edx\n"
95 "lea (%ecx,%edx,1),%ecx\n"
96 "mov %ecx,0x10(%eax)\n"
97 "mov %ecx,0xc(%eax)\n"
98 "mov 0xc(%esp),%ecx\n"
99 "mov %ecx,0x2c(%eax)\n"
100 "stmxcsr (%eax)\n"
101 "fnstcw 0x4(%eax)\n"
102 "mov $finish,%ecx\n"
103 "mov %ecx,0x30(%eax)\n"
104 "mov %fs:0x0,%ecx\n"
105 "walk:\n"
106 "mov (%ecx),%edx\n"
107 "inc %edx\n"
108 "je found\n"
109 "dec %edx\n"
110 "xchg %edx,%ecx\n"
111 "jmp walk\n"
112 "found:\n"
113 "mov 0x4(%ecx),%ecx\n"
114 "mov %ecx,0x3c(%eax)\n"
115 "mov $0xffffffff,%ecx\n"
116 "mov %ecx,0x38(%eax)\n"
117 "lea 0x38(%eax),%ecx\n"
118 "mov %ecx,0x18(%eax)\n"
119 "ret\n"
120 "finish:\n"
121 "xor %eax,%eax\n"
122 "mov %eax,(%esp)\n"
123 "call _exit\n"
124 "hlt\n"
125 ".def __exit; .scl 2; .type 32; .endef \n"
126 );
127 
128 #endif
129 
130 #if defined(LIBCONTEXT_PLATFORM_windows_x86_64) && defined(LIBCONTEXT_COMPILER_gcc)
131 __asm (
132 ".text\n"
133 ".p2align 4,,15\n"
134 ".globl jump_fcontext\n"
135 ".def jump_fcontext; .scl 2; .type 32; .endef\n"
136 ".seh_proc jump_fcontext\n"
137 "jump_fcontext:\n"
138 ".seh_endprologue\n"
139 " push %rbp\n"
140 " push %rbx\n"
141 " push %rsi\n"
142 " push %rdi\n"
143 " push %r15\n"
144 " push %r14\n"
145 " push %r13\n"
146 " push %r12\n"
147 " mov %gs:0x30,%r10\n"
148 " mov 0x8(%r10),%rax\n"
149 " push %rax\n"
150 " mov 0x10(%r10),%rax\n"
151 " push %rax\n"
152 " mov 0x1478(%r10),%rax\n"
153 " push %rax\n"
154 " mov 0x18(%r10),%rax\n"
155 " push %rax\n"
156 " lea -0xa8(%rsp),%rsp\n"
157 " test %r9,%r9\n"
158 " je nxt1\n"
159 " stmxcsr 0xa0(%rsp)\n"
160 " fnstcw 0xa4(%rsp)\n"
161 " movaps %xmm6,(%rsp)\n"
162 " movaps %xmm7,0x10(%rsp)\n"
163 " movaps %xmm8,0x20(%rsp)\n"
164 " movaps %xmm9,0x30(%rsp)\n"
165 " movaps %xmm10,0x40(%rsp)\n"
166 " movaps %xmm11,0x50(%rsp)\n"
167 " movaps %xmm12,0x60(%rsp)\n"
168 " movaps %xmm13,0x70(%rsp)\n"
169 " movaps %xmm14,0x80(%rsp)\n"
170 " movaps %xmm15,0x90(%rsp)\n"
171 "nxt1:\n"
172 " xor %r10,%r10\n"
173 " push %r10\n"
174 " mov %rsp,(%rcx)\n"
175 " mov %rdx,%rsp\n"
176 " pop %r10\n"
177 " test %r9,%r9\n"
178 " je nxt2\n"
179 " ldmxcsr 0xa0(%rsp)\n"
180 " fldcw 0xa4(%rsp)\n"
181 " movaps (%rsp),%xmm6\n"
182 " movaps 0x10(%rsp),%xmm7\n"
183 " movaps 0x20(%rsp),%xmm8\n"
184 " movaps 0x30(%rsp),%xmm9\n"
185 " movaps 0x40(%rsp),%xmm10\n"
186 " movaps 0x50(%rsp),%xmm11\n"
187 " movaps 0x60(%rsp),%xmm12\n"
188 " movaps 0x70(%rsp),%xmm13\n"
189 " movaps 0x80(%rsp),%xmm14\n"
190 " movaps 0x90(%rsp),%xmm15\n"
191 "nxt2:\n"
192 " mov $0xa8,%rcx\n"
193 " test %r10,%r10\n"
194 " je nxt3\n"
195 " add $0x8,%rcx\n"
196 "nxt3:\n"
197 " lea (%rsp,%rcx,1),%rsp\n"
198 " mov %gs:0x30,%r10\n"
199 " pop %rax\n"
200 " mov %rax,0x18(%r10)\n"
201 " pop %rax\n"
202 " mov %rax,0x1478(%r10)\n"
203 " pop %rax\n"
204 " mov %rax,0x10(%r10)\n"
205 " pop %rax\n"
206 " mov %rax,0x8(%r10)\n"
207 " pop %r12\n"
208 " pop %r13\n"
209 " pop %r14\n"
210 " pop %r15\n"
211 " pop %rdi\n"
212 " pop %rsi\n"
213 " pop %rbx\n"
214 " pop %rbp\n"
215 " pop %r10\n"
216 " mov %r8,%rax\n"
217 " mov %r8,%rcx\n"
218 " jmpq *%r10\n"
219 ".seh_endproc\n"
220 );
221 
222 #endif
223 
224 #if defined(LIBCONTEXT_PLATFORM_windows_x86_64) && defined(LIBCONTEXT_COMPILER_gcc)
225 __asm (
226 ".text\n"
227 ".p2align 4,,15\n"
228 ".globl make_fcontext\n"
229 ".def make_fcontext; .scl 2; .type 32; .endef\n"
230 ".seh_proc make_fcontext\n"
231 "make_fcontext:\n"
232 ".seh_endprologue\n"
233 "mov %rcx,%rax\n"
234 "sub $0x28,%rax\n"
235 "and $0xfffffffffffffff0,%rax\n"
236 "sub $0x128,%rax\n"
237 "mov %r8,0x118(%rax)\n"
238 "mov %rcx,0xd0(%rax)\n"
239 "neg %rdx\n"
240 "lea (%rcx,%rdx,1),%rcx\n"
241 "mov %rcx,0xc8(%rax)\n"
242 "mov %rcx,0xc0(%rax)\n"
243 "stmxcsr 0xa8(%rax)\n"
244 "fnstcw 0xac(%rax)\n"
245 "leaq finish(%rip), %rcx\n"
246 "mov %rcx,0x120(%rax)\n"
247 "mov $0x1,%rcx\n"
248 "mov %rcx,(%rax)\n"
249 "retq\n"
250 "finish:\n"
251 "xor %rcx,%rcx\n"
252 "callq 0x63\n"
253 "hlt\n"
254 " .seh_endproc\n"
255 ".def _exit; .scl 2; .type 32; .endef \n"
256 );
257 
258 #endif
259 
260 #if defined(LIBCONTEXT_PLATFORM_linux_i386) && defined(LIBCONTEXT_COMPILER_gcc)
261 __asm (
262 ".text\n"
263 ".globl jump_fcontext\n"
264 ".align 2\n"
265 ".type jump_fcontext,@function\n"
266 "jump_fcontext:\n"
267 " movl 0x10(%esp), %ecx\n"
268 " pushl %ebp \n"
269 " pushl %ebx \n"
270 " pushl %esi \n"
271 " pushl %edi \n"
272 " leal -0x8(%esp), %esp\n"
273 " test %ecx, %ecx\n"
274 " je 1f\n"
275 " stmxcsr (%esp)\n"
276 " fnstcw 0x4(%esp)\n"
277 "1:\n"
278 " movl 0x1c(%esp), %eax\n"
279 " movl %esp, (%eax)\n"
280 " movl 0x20(%esp), %edx\n"
281 " movl 0x24(%esp), %eax\n"
282 " movl %edx, %esp\n"
283 " test %ecx, %ecx\n"
284 " je 2f\n"
285 " ldmxcsr (%esp)\n"
286 " fldcw 0x4(%esp)\n"
287 "2:\n"
288 " leal 0x8(%esp), %esp\n"
289 " popl %edi \n"
290 " popl %esi \n"
291 " popl %ebx \n"
292 " popl %ebp \n"
293 " popl %edx\n"
294 " movl %eax, 0x4(%esp)\n"
295 " jmp *%edx\n"
296 ".size jump_fcontext,.-jump_fcontext\n"
297 ".section .note.GNU-stack,\"\",%progbits\n"
298 );
299 
300 #endif
301 
302 #if defined(LIBCONTEXT_PLATFORM_linux_i386) && defined(LIBCONTEXT_COMPILER_gcc)
303 __asm (
304 ".text\n"
305 ".globl make_fcontext\n"
306 ".align 2\n"
307 ".type make_fcontext,@function\n"
308 "make_fcontext:\n"
309 " movl 0x4(%esp), %eax\n"
310 " leal -0x8(%eax), %eax\n"
311 " andl $-16, %eax\n"
312 " leal -0x20(%eax), %eax\n"
313 " movl 0xc(%esp), %edx\n"
314 " movl %edx, 0x18(%eax)\n"
315 " stmxcsr (%eax)\n"
316 " fnstcw 0x4(%eax)\n"
317 " call 1f\n"
318 "1: popl %ecx\n"
319 " addl $finish-1b, %ecx\n"
320 " movl %ecx, 0x1c(%eax)\n"
321 " ret \n"
322 "finish:\n"
323 " call 2f\n"
324 "2: popl %ebx\n"
325 " addl $_GLOBAL_OFFSET_TABLE_+[.-2b], %ebx\n"
326 " xorl %eax, %eax\n"
327 " movl %eax, (%esp)\n"
328 " call _exit@PLT\n"
329 " hlt\n"
330 ".size make_fcontext,.-make_fcontext\n"
331 ".section .note.GNU-stack,\"\",%progbits\n"
332 );
333 
334 #endif
335 
336 #if defined(LIBCONTEXT_PLATFORM_linux_x86_64) && defined(LIBCONTEXT_COMPILER_gcc)
337 __asm (
338 ".text\n"
339 ".globl jump_fcontext\n"
340 ".type jump_fcontext,@function\n"
341 ".align 16\n"
342 "jump_fcontext:\n"
343 " pushq %rbp \n"
344 " pushq %rbx \n"
345 " pushq %r15 \n"
346 " pushq %r14 \n"
347 " pushq %r13 \n"
348 " pushq %r12 \n"
349 " leaq -0x8(%rsp), %rsp\n"
350 " cmp $0, %rcx\n"
351 " je 1f\n"
352 " stmxcsr (%rsp)\n"
353 " fnstcw 0x4(%rsp)\n"
354 "1:\n"
355 " movq %rsp, (%rdi)\n"
356 " movq %rsi, %rsp\n"
357 " cmp $0, %rcx\n"
358 " je 2f\n"
359 " ldmxcsr (%rsp)\n"
360 " fldcw 0x4(%rsp)\n"
361 "2:\n"
362 " leaq 0x8(%rsp), %rsp\n"
363 " popq %r12 \n"
364 " popq %r13 \n"
365 " popq %r14 \n"
366 " popq %r15 \n"
367 " popq %rbx \n"
368 " popq %rbp \n"
369 " popq %r8\n"
370 " movq %rdx, %rax\n"
371 " movq %rdx, %rdi\n"
372 " jmp *%r8\n"
373 ".size jump_fcontext,.-jump_fcontext\n"
374 ".section .note.GNU-stack,\"\",%progbits\n"
375 );
376 
377 #endif
378 
379 #if defined(LIBCONTEXT_PLATFORM_linux_x86_64) && defined(LIBCONTEXT_COMPILER_gcc)
380 __asm (
381 ".text\n"
382 ".globl make_fcontext\n"
383 ".type make_fcontext,@function\n"
384 ".align 16\n"
385 "make_fcontext:\n"
386 " movq %rdi, %rax\n"
387 " andq $-16, %rax\n"
388 " leaq -0x48(%rax), %rax\n"
389 " movq %rdx, 0x38(%rax)\n"
390 " stmxcsr (%rax)\n"
391 " fnstcw 0x4(%rax)\n"
392 " leaq finish(%rip), %rcx\n"
393 " movq %rcx, 0x40(%rax)\n"
394 " ret \n"
395 "finish:\n"
396 " xorq %rdi, %rdi\n"
397 " call _exit@PLT\n"
398 " hlt\n"
399 ".size make_fcontext,.-make_fcontext\n"
400 ".section .note.GNU-stack,\"\",%progbits\n"
401 );
402 
403 #endif
404 
405 #if defined(LIBCONTEXT_PLATFORM_apple_x86_64) && defined(LIBCONTEXT_COMPILER_gcc)
406 __asm (
407 ".text\n"
408 ".globl _jump_fcontext\n"
409 ".align 8\n"
410 "_jump_fcontext:\n"
411 " pushq %rbp \n"
412 " pushq %rbx \n"
413 " pushq %r15 \n"
414 " pushq %r14 \n"
415 " pushq %r13 \n"
416 " pushq %r12 \n"
417 " leaq -0x8(%rsp), %rsp\n"
418 " cmp $0, %rcx\n"
419 " je 1f\n"
420 " stmxcsr (%rsp)\n"
421 " fnstcw 0x4(%rsp)\n"
422 "1:\n"
423 " movq %rsp, (%rdi)\n"
424 " movq %rsi, %rsp\n"
425 " cmp $0, %rcx\n"
426 " je 2f\n"
427 " ldmxcsr (%rsp)\n"
428 " fldcw 0x4(%rsp)\n"
429 "2:\n"
430 " leaq 0x8(%rsp), %rsp\n"
431 " popq %r12 \n"
432 " popq %r13 \n"
433 " popq %r14 \n"
434 " popq %r15 \n"
435 " popq %rbx \n"
436 " popq %rbp \n"
437 " popq %r8\n"
438 " movq %rdx, %rax\n"
439 " movq %rdx, %rdi\n"
440 " jmp *%r8\n"
441 );
442 
443 #endif
444 
445 #if defined(LIBCONTEXT_PLATFORM_apple_x86_64) && defined(LIBCONTEXT_COMPILER_gcc)
446 __asm (
447 ".text\n"
448 ".globl _make_fcontext\n"
449 ".align 8\n"
450 "_make_fcontext:\n"
451 " movq %rdi, %rax\n"
452 " movabs $-16, %r8\n"
453 " andq %r8, %rax\n"
454 " leaq -0x48(%rax), %rax\n"
455 " movq %rdx, 0x38(%rax)\n"
456 " stmxcsr (%rax)\n"
457 " fnstcw 0x4(%rax)\n"
458 " leaq finish(%rip), %rcx\n"
459 " movq %rcx, 0x40(%rax)\n"
460 " ret \n"
461 "finish:\n"
462 " xorq %rdi, %rdi\n"
463 " call __exit\n"
464 " hlt\n"
465 );
466 
467 #endif
468 
469 #if defined(LIBCONTEXT_PLATFORM_apple_i386) && defined(LIBCONTEXT_COMPILER_gcc)
470 __asm (
471 ".text\n"
472 ".globl _jump_fcontext\n"
473 ".align 2\n"
474 "_jump_fcontext:\n"
475 " movl 0x10(%esp), %ecx\n"
476 " pushl %ebp \n"
477 " pushl %ebx \n"
478 " pushl %esi \n"
479 " pushl %edi \n"
480 " leal -0x8(%esp), %esp\n"
481 " test %ecx, %ecx\n"
482 " je 1f\n"
483 " stmxcsr (%esp)\n"
484 " fnstcw 0x4(%esp)\n"
485 "1:\n"
486 " movl 0x1c(%esp), %eax\n"
487 " movl %esp, (%eax)\n"
488 " movl 0x20(%esp), %edx\n"
489 " movl 0x24(%esp), %eax\n"
490 " movl %edx, %esp\n"
491 " test %ecx, %ecx\n"
492 " je 2f\n"
493 " ldmxcsr (%esp)\n"
494 " fldcw 0x4(%esp)\n"
495 "2:\n"
496 " leal 0x8(%esp), %esp\n"
497 " popl %edi \n"
498 " popl %esi \n"
499 " popl %ebx \n"
500 " popl %ebp \n"
501 " popl %edx\n"
502 " movl %eax, 0x4(%esp)\n"
503 " jmp *%edx\n"
504 );
505 
506 #endif
507 
508 #if defined(LIBCONTEXT_PLATFORM_apple_i386) && defined(LIBCONTEXT_COMPILER_gcc)
509 __asm (
510 ".text\n"
511 ".globl _make_fcontext\n"
512 ".align 2\n"
513 "_make_fcontext:\n"
514 " movl 0x4(%esp), %eax\n"
515 " leal -0x8(%eax), %eax\n"
516 " andl $-16, %eax\n"
517 " leal -0x20(%eax), %eax\n"
518 " movl 0xc(%esp), %edx\n"
519 " movl %edx, 0x18(%eax)\n"
520 " stmxcsr (%eax)\n"
521 " fnstcw 0x4(%eax)\n"
522 " call 1f\n"
523 "1: popl %ecx\n"
524 " addl $finish-1b, %ecx\n"
525 " movl %ecx, 0x1c(%eax)\n"
526 " ret \n"
527 "finish:\n"
528 " xorl %eax, %eax\n"
529 " movl %eax, (%esp)\n"
530 " call __exit\n"
531 " hlt\n"
532 );
533 
534 #endif
535 
536 #if defined(LIBCONTEXT_PLATFORM_linux_arm32) && defined(LIBCONTEXT_COMPILER_gcc)
537 __asm (
538 ".text\n"
539 ".globl jump_fcontext\n"
540 ".align 2\n"
541 ".type jump_fcontext,%function\n"
542 "jump_fcontext:\n"
543 " @ save LR as PC\n"
544 " push {lr}\n"
545 " @ save V1-V8,LR\n"
546 " push {v1-v8,lr}\n"
547 " @ prepare stack for FPU\n"
548 " sub sp, sp, #64\n"
549 " @ test if fpu env should be preserved\n"
550 " cmp a4, #0\n"
551 " beq 1f\n"
552 " @ save S16-S31\n"
553 " vstmia sp, {d8-d15}\n"
554 "1:\n"
555 " @ store RSP (pointing to context-data) in A1\n"
556 " str sp, [a1]\n"
557 " @ restore RSP (pointing to context-data) from A2\n"
558 " mov sp, a2\n"
559 " @ test if fpu env should be preserved\n"
560 " cmp a4, #0\n"
561 " beq 2f\n"
562 " @ restore S16-S31\n"
563 " vldmia sp, {d8-d15}\n"
564 "2:\n"
565 " @ prepare stack for FPU\n"
566 " add sp, sp, #64\n"
567 " @ use third arg as return value after jump\n"
568 " @ and as first arg in context function\n"
569 " mov a1, a3\n"
570 " @ restore v1-V8,LR,PC\n"
571 " pop {v1-v8,lr}\n"
572 " pop {pc}\n"
573 ".size jump_fcontext,.-jump_fcontext\n"
574 "@ Mark that we don't need executable stack.\n"
575 ".section .note.GNU-stack,\"\",%progbits\n"
576 );
577 
578 #endif
579 
580 #if defined(LIBCONTEXT_PLATFORM_linux_arm32) && defined(LIBCONTEXT_COMPILER_gcc)
581 __asm (
582 ".text\n"
583 ".globl make_fcontext\n"
584 ".align 2\n"
585 ".type make_fcontext,%function\n"
586 "make_fcontext:\n"
587 " @ shift address in A1 to lower 16 byte boundary\n"
588 " bic a1, a1, #15\n"
589 " @ reserve space for context-data on context-stack\n"
590 " sub a1, a1, #104\n"
591 " @ third arg of make_fcontext() == address of context-function\n"
592 " str a3, [a1,#100]\n"
593 " @ compute abs address of label finish\n"
594 " adr a2, finish\n"
595 " @ save address of finish as return-address for context-function\n"
596 " @ will be entered after context-function returns\n"
597 " str a2, [a1,#96]\n"
598 " bx lr @ return pointer to context-data\n"
599 "finish:\n"
600 " @ exit code is zero\n"
601 " mov a1, #0\n"
602 " @ exit application\n"
603 " bl _exit@PLT\n"
604 ".size make_fcontext,.-make_fcontext\n"
605 "@ Mark that we don't need executable stack.\n"
606 ".section .note.GNU-stack,\"\",%progbits\n"
607 );
608 
609 #endif
610 
611 #if defined(LIBCONTEXT_PLATFORM_linux_arm64) && defined(LIBCONTEXT_COMPILER_gcc)
612 __asm (
613 ".cpu generic+fp+simd\n"
614 ".text\n"
615 ".align 2\n"
616 ".global jump_fcontext\n"
617 ".type jump_fcontext, %function\n"
618 "jump_fcontext:\n"
619 " # prepare stack for GP + FPU\n"
620 " sub sp, sp, #0xb0\n"
621 "# Because gcc may save integer registers in fp registers across a\n"
622 "# function call we cannot skip saving the fp registers.\n"
623 "#\n"
624 "# Do not reinstate this test unless you fully understand what you\n"
625 "# are doing.\n"
626 "#\n"
627 "# # test if fpu env should be preserved\n"
628 "# cmp w3, #0\n"
629 "# b.eq 1f\n"
630 " # save d8 - d15\n"
631 " stp d8, d9, [sp, #0x00]\n"
632 " stp d10, d11, [sp, #0x10]\n"
633 " stp d12, d13, [sp, #0x20]\n"
634 " stp d14, d15, [sp, #0x30]\n"
635 "1:\n"
636 " # save x19-x30\n"
637 " stp x19, x20, [sp, #0x40]\n"
638 " stp x21, x22, [sp, #0x50]\n"
639 " stp x23, x24, [sp, #0x60]\n"
640 " stp x25, x26, [sp, #0x70]\n"
641 " stp x27, x28, [sp, #0x80]\n"
642 " stp x29, x30, [sp, #0x90]\n"
643 " # save LR as PC\n"
644 " str x30, [sp, #0xa0]\n"
645 " # store RSP (pointing to context-data) in first argument (x0).\n"
646 " # STR cannot have sp as a target register\n"
647 " mov x4, sp\n"
648 " str x4, [x0]\n"
649 " # restore RSP (pointing to context-data) from A2 (x1)\n"
650 " mov sp, x1\n"
651 "# # test if fpu env should be preserved\n"
652 "# cmp w3, #0\n"
653 "# b.eq 2f\n"
654 " # load d8 - d15\n"
655 " ldp d8, d9, [sp, #0x00]\n"
656 " ldp d10, d11, [sp, #0x10]\n"
657 " ldp d12, d13, [sp, #0x20]\n"
658 " ldp d14, d15, [sp, #0x30]\n"
659 "2:\n"
660 " # load x19-x30\n"
661 " ldp x19, x20, [sp, #0x40]\n"
662 " ldp x21, x22, [sp, #0x50]\n"
663 " ldp x23, x24, [sp, #0x60]\n"
664 " ldp x25, x26, [sp, #0x70]\n"
665 " ldp x27, x28, [sp, #0x80]\n"
666 " ldp x29, x30, [sp, #0x90]\n"
667 " # use third arg as return value after jump\n"
668 " # and as first arg in context function\n"
669 " mov x0, x2\n"
670 " # load pc\n"
671 " ldr x4, [sp, #0xa0]\n"
672 " # restore stack from GP + FPU\n"
673 " add sp, sp, #0xb0\n"
674 " ret x4\n"
675 ".size jump_fcontext,.-jump_fcontext\n"
676 "# Mark that we don't need executable stack.\n"
677 ".section .note.GNU-stack,\"\",%progbits\n"
678 );
679 
680 #endif
681 
682 #if defined(LIBCONTEXT_PLATFORM_linux_arm64) && defined(LIBCONTEXT_COMPILER_gcc)
683 __asm (
684 ".cpu generic+fp+simd\n"
685 ".text\n"
686 ".align 2\n"
687 ".global make_fcontext\n"
688 ".type make_fcontext, %function\n"
689 "make_fcontext:\n"
690 " # shift address in x0 (allocated stack) to lower 16 byte boundary\n"
691 " and x0, x0, ~0xF\n"
692 " # reserve space for context-data on context-stack\n"
693 " sub x0, x0, #0xb0\n"
694 " # third arg of make_fcontext() == address of context-function\n"
695 " # store address as a PC to jump in\n"
696 " str x2, [x0, #0xa0]\n"
697 " # save address of finish as return-address for context-function\n"
698 " # will be entered after context-function returns (LR register)\n"
699 " adr x1, finish\n"
700 " str x1, [x0, #0x98]\n"
701 " ret x30 \n"
702 "finish:\n"
703 " # exit code is zero\n"
704 " mov x0, #0\n"
705 " # exit application\n"
706 " bl _exit\n"
707 ".size make_fcontext,.-make_fcontext\n"
708 "# Mark that we don't need executable stack.\n"
709 ".section .note.GNU-stack,\"\",%progbits\n"
710 );
711 
712 #endif
713 
714 #if defined(LIBCONTEXT_PLATFORM_linux_mips_n64) && defined(LIBCONTEXT_COMPILER_gcc)
715 __asm (
716 ".text\n"
717 ".globl jump_fcontext\n"
718 ".align 2\n"
719 ".set noreorder\n"
720 ".type jump_fcontext,@function\n"
721 ".ent jump_fcontext\n"
722 "jump_fcontext:\n"
723 " # reserve space on stack\n"
724 " daddiu $sp, $sp, -176\n"
725 " sd $s0, 64($sp) # save S0\n"
726 " sd $s1, 72($sp) # save S1\n"
727 " sd $s2, 80($sp) # save S2\n"
728 " sd $s3, 88($sp) # save S3\n"
729 " sd $s4, 96($sp) # save S4\n"
730 " sd $s5, 104($sp) # save S5\n"
731 " sd $s6, 112($sp) # save S6\n"
732 " sd $s7, 120($sp) # save S7\n"
733 " sd $fp, 128($sp) # save FP\n"
734 " sd $ra, 144($sp) # save RA\n"
735 " sd $ra, 152($sp) # save RA as PC\n"
736 " s.d $f24, 0($sp) # save F24\n"
737 " s.d $f25, 8($sp) # save F25\n"
738 " s.d $f26, 16($sp) # save F26\n"
739 " s.d $f27, 24($sp) # save F27\n"
740 " s.d $f28, 32($sp) # save F28\n"
741 " s.d $f29, 40($sp) # save F29\n"
742 " s.d $f30, 48($sp) # save F30\n"
743 " s.d $f31, 56($sp) # save F31\n"
744 " # store SP (pointing to old context-data) in pointer a0(first arg)\n"
745 " sd $sp, 0($a0)\n"
746 " # get SP (pointing to new context-data) from a1 param\n"
747 " move $sp, $a1\n"
748 " l.d $f24, 0($sp) # restore F24\n"
749 " l.d $f25, 8($sp) # restore F25\n"
750 " l.d $f26, 16($sp) # restore F26\n"
751 " l.d $f27, 24($sp) # restore F27\n"
752 " l.d $f28, 32($sp) # restore F28\n"
753 " l.d $f29, 40($sp) # restore F29\n"
754 " l.d $f30, 48($sp) # restore F30\n"
755 " l.d $f31, 56($sp) # restore F31\n"
756 " ld $s0, 64($sp) # restore S0\n"
757 " ld $s1, 72($sp) # restore S1\n"
758 " ld $s2, 80($sp) # restore S2\n"
759 " ld $s3, 88($sp) # restore S3\n"
760 " ld $s4, 96($sp) # restore S4\n"
761 " ld $s5, 104($sp) # restore S5\n"
762 " ld $s6, 112($sp) # restore S6\n"
763 " ld $s7, 120($sp) # restore S7\n"
764 " ld $fp, 128($sp) # restore FP\n"
765 " ld $ra, 144($sp) # restore RA\n"
766 " # load PC\n"
767 " ld $t9, 152($sp)\n"
768 " sd $a2, 160($sp)\n"
769 " # adjust stack\n"
770 " daddiu $sp, $sp, 176\n"
771 " move $a0, $a2 # move *data from a2 to a0 as param\n"
772 " move $v0, $a2 # move *data from a2 to v0 as return\n"
773 " # jump to context\n"
774 " jr $t9\n"
775 " nop\n"
776 ".end jump_fcontext\n"
777 ".size jump_fcontext, .-jump_fcontext\n"
778 ".section .note.GNU-stack,\"\",%progbits\n"
779 );
780 
781 #endif
782 
783 #if defined(LIBCONTEXT_PLATFORM_linux_mips_n64) && defined(LIBCONTEXT_COMPILER_gcc)
784 __asm (
785 ".text\n"
786 ".globl make_fcontext\n"
787 ".align 2\n"
788 ".set noreorder\n"
789 ".type make_fcontext,@function\n"
790 ".ent make_fcontext\n"
791 "make_fcontext:\n"
792 "#ifdef __PIC__\n"
793 ".set noreorder\n"
794 ".cpload $t9\n"
795 ".set reorder\n"
796 "#endif\n"
797 " # shift address in A0 to lower 16 byte boundary\n"
798 " li $v1, 0xfffffffffffffff0\n"
799 " and $v0, $v1, $a0\n"
800 " # reserve space for context-data on context-stack\n"
801 " daddiu $v0, $v0, -176\n"
802 " # third arg of make_fcontext() == address of context-function\n"
803 " sd $a2, 152($v0)\n"
804 " # save global pointer in context-data\n"
805 " sd $gp, 136($v0)\n"
806 " # psudo instruction compute abs address of label finish based on GP\n"
807 " dla $t9, finish\n"
808 " # save address of finish as return-address for context-function\n"
809 " # will be entered after context-function returns\n"
810 " sd $t9, 144($v0)\n"
811 " jr $ra # return pointer to context-data\n"
812 " nop\n"
813 "finish:\n"
814 " # reload our gp register (needed for la)\n"
815 " daddiu $t0, $sp, -176\n"
816 " ld $gp, 136($t0)\n"
817 " ld $v0, 160($t0)\n"
818 " # call _exit(0)\n"
819 " dla $t9, _exit\n"
820 " move $a0, $zero\n"
821 " jr $t9\n"
822 " nop\n"
823 ".end make_fcontext\n"
824 ".size make_fcontext, .-make_fcontext\n"
825 ".section .note.GNU-stack,\"\",%progbits\n"
826 );
827 
828 #endif
829 
830 #if defined(LIBCONTEXT_PLATFORM_linux_ppc32) && defined(LIBCONTEXT_COMPILER_gcc)
831 __asm (
832 ".text\n"
833 ".globl jump_fcontext\n"
834 ".align 2\n"
835 ".type jump_fcontext,@function\n"
836 "jump_fcontext:\n"
837 " # reserve space on stack\n"
838 " subi %r1, %r1, 240\n"
839 " stw %r13, 152(%r1) # save R13\n"
840 " stw %r14, 156(%r1) # save R14\n"
841 " stw %r15, 160(%r1) # save R15\n"
842 " stw %r16, 164(%r1) # save R16\n"
843 " stw %r17, 168(%r1) # save R17\n"
844 " stw %r18, 172(%r1) # save R18\n"
845 " stw %r19, 176(%r1) # save R19\n"
846 " stw %r20, 180(%r1) # save R20\n"
847 " stw %r21, 184(%r1) # save R21\n"
848 " stw %r22, 188(%r1) # save R22\n"
849 " stw %r23, 192(%r1) # save R23\n"
850 " stw %r24, 196(%r1) # save R24\n"
851 " stw %r25, 200(%r1) # save R25\n"
852 " stw %r26, 204(%r1) # save R26\n"
853 " stw %r27, 208(%r1) # save R27\n"
854 " stw %r28, 212(%r1) # save R28\n"
855 " stw %r29, 216(%r1) # save R29\n"
856 " stw %r30, 220(%r1) # save R30\n"
857 " stw %r31, 224(%r1) # save R31\n"
858 " # save CR\n"
859 " mfcr %r0\n"
860 " stw %r0, 228(%r1)\n"
861 " # save LR\n"
862 " mflr %r0\n"
863 " stw %r0, 232(%r1)\n"
864 " # save LR as PC\n"
865 " stw %r0, 236(%r1)\n"
866 " # test if fpu env should be preserved\n"
867 " cmpwi cr7, %r6, 0\n"
868 " beq cr7, 1f\n"
869 " stfd %f14, 0(%r1) # save F14\n"
870 " stfd %f15, 8(%r1) # save F15\n"
871 " stfd %f16, 16(%r1) # save F16\n"
872 " stfd %f17, 24(%r1) # save F17\n"
873 " stfd %f18, 32(%r1) # save F18\n"
874 " stfd %f19, 40(%r1) # save F19\n"
875 " stfd %f20, 48(%r1) # save F20\n"
876 " stfd %f21, 56(%r1) # save F21\n"
877 " stfd %f22, 64(%r1) # save F22\n"
878 " stfd %f23, 72(%r1) # save F23\n"
879 " stfd %f24, 80(%r1) # save F24\n"
880 " stfd %f25, 88(%r1) # save F25\n"
881 " stfd %f26, 96(%r1) # save F26\n"
882 " stfd %f27, 104(%r1) # save F27\n"
883 " stfd %f28, 112(%r1) # save F28\n"
884 " stfd %f29, 120(%r1) # save F29\n"
885 " stfd %f30, 128(%r1) # save F30\n"
886 " stfd %f31, 136(%r1) # save F31\n"
887 " mffs %f0 # load FPSCR\n"
888 " stfd %f0, 144(%r1) # save FPSCR\n"
889 "1:\n"
890 " # store RSP (pointing to context-data) in R3\n"
891 " stw %r1, 0(%r3)\n"
892 " # restore RSP (pointing to context-data) from R4\n"
893 " mr %r1, %r4\n"
894 " # test if fpu env should be preserved\n"
895 " cmpwi cr7, %r6, 0\n"
896 " beq cr7, 2f\n"
897 " lfd %f14, 0(%r1) # restore F14\n"
898 " lfd %f15, 8(%r1) # restore F15\n"
899 " lfd %f16, 16(%r1) # restore F16\n"
900 " lfd %f17, 24(%r1) # restore F17\n"
901 " lfd %f18, 32(%r1) # restore F18\n"
902 " lfd %f19, 40(%r1) # restore F19\n"
903 " lfd %f20, 48(%r1) # restore F20\n"
904 " lfd %f21, 56(%r1) # restore F21\n"
905 " lfd %f22, 64(%r1) # restore F22\n"
906 " lfd %f23, 72(%r1) # restore F23\n"
907 " lfd %f24, 80(%r1) # restore F24\n"
908 " lfd %f25, 88(%r1) # restore F25\n"
909 " lfd %f26, 96(%r1) # restore F26\n"
910 " lfd %f27, 104(%r1) # restore F27\n"
911 " lfd %f28, 112(%r1) # restore F28\n"
912 " lfd %f29, 120(%r1) # restore F29\n"
913 " lfd %f30, 128(%r1) # restore F30\n"
914 " lfd %f31, 136(%r1) # restore F31\n"
915 " lfd %f0, 144(%r1) # load FPSCR\n"
916 " mtfsf 0xff, %f0 # restore FPSCR\n"
917 "2:\n"
918 " lwz %r13, 152(%r1) # restore R13\n"
919 " lwz %r14, 156(%r1) # restore R14\n"
920 " lwz %r15, 160(%r1) # restore R15\n"
921 " lwz %r16, 164(%r1) # restore R16\n"
922 " lwz %r17, 168(%r1) # restore R17\n"
923 " lwz %r18, 172(%r1) # restore R18\n"
924 " lwz %r19, 176(%r1) # restore R19\n"
925 " lwz %r20, 180(%r1) # restore R20\n"
926 " lwz %r21, 184(%r1) # restore R21\n"
927 " lwz %r22, 188(%r1) # restore R22\n"
928 " lwz %r23, 192(%r1) # restore R23\n"
929 " lwz %r24, 196(%r1) # restore R24\n"
930 " lwz %r25, 200(%r1) # restore R25\n"
931 " lwz %r26, 204(%r1) # restore R26\n"
932 " lwz %r27, 208(%r1) # restore R27\n"
933 " lwz %r28, 212(%r1) # restore R28\n"
934 " lwz %r29, 216(%r1) # restore R29\n"
935 " lwz %r30, 220(%r1) # restore R30\n"
936 " lwz %r31, 224(%r1) # restore R31\n"
937 " # restore CR\n"
938 " lwz %r0, 228(%r1)\n"
939 " mtcr %r0\n"
940 " # restore LR\n"
941 " lwz %r0, 232(%r1)\n"
942 " mtlr %r0\n"
943 " # load PC\n"
944 " lwz %r0, 236(%r1)\n"
945 " # restore CTR\n"
946 " mtctr %r0\n"
947 " # adjust stack\n"
948 " addi %r1, %r1, 240\n"
949 " # use third arg as return value after jump\n"
950 " # use third arg as first arg in context function\n"
951 " mr %r3, %r5\n"
952 " # jump to context\n"
953 " bctr\n"
954 ".size jump_fcontext, .-jump_fcontext\n"
955 ".section .note.GNU-stack,\"\",%progbits\n"
956 );
957 
958 #endif
959 
960 #if defined(LIBCONTEXT_PLATFORM_linux_ppc32) && defined(LIBCONTEXT_COMPILER_gcc)
961 __asm (
962 ".text\n"
963 ".globl make_fcontext\n"
964 ".align 2\n"
965 ".type make_fcontext,@function\n"
966 "make_fcontext:\n"
967 " # save return address into R6\n"
968 " mflr %r6\n"
969 " # first arg of make_fcontext() == top address of context-function\n"
970 " # shift address in R3 to lower 16 byte boundary\n"
971 " clrrwi %r3, %r3, 4\n"
972 " # reserve space for context-data on context-stack\n"
973 " # including 64 byte of linkage + parameter area (R1 % 16 == 0)\n"
974 " subi %r3, %r3, 304\n"
975 " # third arg of make_fcontext() == address of context-function\n"
976 " stw %r5, 236(%r3)\n"
977 " # load LR\n"
978 " mflr %r0\n"
979 " # jump to label 1\n"
980 " bl 1f\n"
981 "1:\n"
982 " # load LR into R4\n"
983 " mflr %r4\n"
984 " # compute abs address of label finish\n"
985 " addi %r4, %r4, finish - 1b\n"
986 " # restore LR\n"
987 " mtlr %r0\n"
988 " # save address of finish as return-address for context-function\n"
989 " # will be entered after context-function returns\n"
990 " stw %r4, 232(%r3)\n"
991 " # restore return address from R6\n"
992 " mtlr %r6\n"
993 " blr # return pointer to context-data\n"
994 "finish:\n"
995 " # save return address into R0\n"
996 " mflr %r0\n"
997 " # save return address on stack, set up stack frame\n"
998 " stw %r0, 4(%r1)\n"
999 " # allocate stack space, R1 % 16 == 0\n"
1000 " stwu %r1, -16(%r1)\n"
1001 " # exit code is zero\n"
1002 " li %r3, 0\n"
1003 " # exit application\n"
1004 " bl _exit@plt\n"
1005 ".size make_fcontext, .-make_fcontext\n"
1006 ".section .note.GNU-stack,\"\",%progbits\n"
1007 );
1008 
1009 #endif
1010 
1011 #if defined(LIBCONTEXT_PLATFORM_linux_ppc64) && defined(LIBCONTEXT_COMPILER_gcc)
1012 __asm (
1013 ".globl jump_fcontext\n"
1014 #if _CALL_ELF == 2
1015 " .text\n"
1016 " .align 2\n"
1017 "jump_fcontext:\n"
1018 " addis %r2, %r12, .TOC.-jump_fcontext@ha\n"
1019 " addi %r2, %r2, .TOC.-jump_fcontext@l\n"
1020 " .localentry jump_fcontext, . - jump_fcontext\n"
1021 #else
1022 " .section \".opd\",\"aw\"\n"
1023 " .align 3\n"
1024 "jump_fcontext:\n"
1025 # ifdef _CALL_LINUX
1026 " .quad .L.jump_fcontext,.TOC.@tocbase,0\n"
1027 " .type jump_fcontext,@function\n"
1028 " .text\n"
1029 " .align 2\n"
1030 ".L.jump_fcontext:\n"
1031 # else
1032 " .hidden .jump_fcontext\n"
1033 " .globl .jump_fcontext\n"
1034 " .quad .jump_fcontext,.TOC.@tocbase,0\n"
1035 " .size jump_fcontext,24\n"
1036 " .type .jump_fcontext,@function\n"
1037 " .text\n"
1038 " .align 2\n"
1039 ".jump_fcontext:\n"
1040 # endif
1041 #endif
1042 " # reserve space on stack\n"
1043 " subi %r1, %r1, 328\n"
1044 #if _CALL_ELF != 2
1045 " std %r2, 152(%r1) # save TOC\n"
1046 #endif
1047 " std %r14, 160(%r1) # save R14\n"
1048 " std %r15, 168(%r1) # save R15\n"
1049 " std %r16, 176(%r1) # save R16\n"
1050 " std %r17, 184(%r1) # save R17\n"
1051 " std %r18, 192(%r1) # save R18\n"
1052 " std %r19, 200(%r1) # save R19\n"
1053 " std %r20, 208(%r1) # save R20\n"
1054 " std %r21, 216(%r1) # save R21\n"
1055 " std %r22, 224(%r1) # save R22\n"
1056 " std %r23, 232(%r1) # save R23\n"
1057 " std %r24, 240(%r1) # save R24\n"
1058 " std %r25, 248(%r1) # save R25\n"
1059 " std %r26, 256(%r1) # save R26\n"
1060 " std %r27, 264(%r1) # save R27\n"
1061 " std %r28, 272(%r1) # save R28\n"
1062 " std %r29, 280(%r1) # save R29\n"
1063 " std %r30, 288(%r1) # save R30\n"
1064 " std %r31, 296(%r1) # save R31\n"
1065 " # save CR\n"
1066 " mfcr %r0\n"
1067 " std %r0, 304(%r1)\n"
1068 " # save LR\n"
1069 " mflr %r0\n"
1070 " std %r0, 312(%r1)\n"
1071 " # save LR as PC\n"
1072 " std %r0, 320(%r1)\n"
1073 " # test if fpu env should be preserved\n"
1074 " cmpwi cr7, %r6, 0\n"
1075 " beq cr7, 1f\n"
1076 " stfd %f14, 0(%r1) # save F14\n"
1077 " stfd %f15, 8(%r1) # save F15\n"
1078 " stfd %f16, 16(%r1) # save F16\n"
1079 " stfd %f17, 24(%r1) # save F17\n"
1080 " stfd %f18, 32(%r1) # save F18\n"
1081 " stfd %f19, 40(%r1) # save F19\n"
1082 " stfd %f20, 48(%r1) # save F20\n"
1083 " stfd %f21, 56(%r1) # save F21\n"
1084 " stfd %f22, 64(%r1) # save F22\n"
1085 " stfd %f23, 72(%r1) # save F23\n"
1086 " stfd %f24, 80(%r1) # save F24\n"
1087 " stfd %f25, 88(%r1) # save F25\n"
1088 " stfd %f26, 96(%r1) # save F26\n"
1089 " stfd %f27, 104(%r1) # save F27\n"
1090 " stfd %f28, 112(%r1) # save F28\n"
1091 " stfd %f29, 120(%r1) # save F29\n"
1092 " stfd %f30, 128(%r1) # save F30\n"
1093 " stfd %f31, 136(%r1) # save F31\n"
1094 " mffs %f0 # load FPSCR\n"
1095 " stfd %f0, 144(%r1) # save FPSCR\n"
1096 "1:\n"
1097 " # store RSP (pointing to context-data) in R3\n"
1098 " std %r1, 0(%r3)\n"
1099 " # restore RSP (pointing to context-data) from R4\n"
1100 " mr %r1, %r4\n"
1101 " # test if fpu env should be preserved\n"
1102 " cmpwi cr7, %r6, 0\n"
1103 " beq cr7, 2f\n"
1104 " lfd %f14, 0(%r1) # restore F14\n"
1105 " lfd %f15, 8(%r1) # restore F15\n"
1106 " lfd %f16, 16(%r1) # restore F16\n"
1107 " lfd %f17, 24(%r1) # restore F17\n"
1108 " lfd %f18, 32(%r1) # restore F18\n"
1109 " lfd %f19, 40(%r1) # restore F19\n"
1110 " lfd %f20, 48(%r1) # restore F20\n"
1111 " lfd %f21, 56(%r1) # restore F21\n"
1112 " lfd %f22, 64(%r1) # restore F22\n"
1113 " lfd %f23, 72(%r1) # restore F23\n"
1114 " lfd %f24, 80(%r1) # restore F24\n"
1115 " lfd %f25, 88(%r1) # restore F25\n"
1116 " lfd %f26, 96(%r1) # restore F26\n"
1117 " lfd %f27, 104(%r1) # restore F27\n"
1118 " lfd %f28, 112(%r1) # restore F28\n"
1119 " lfd %f29, 120(%r1) # restore F29\n"
1120 " lfd %f30, 128(%r1) # restore F30\n"
1121 " lfd %f31, 136(%r1) # restore F31\n"
1122 " lfd %f0, 144(%r1) # load FPSCR\n"
1123 " mtfsf 0xff, %f0 # restore FPSCR\n"
1124 "2:\n"
1125 #if _CALL_ELF != 2
1126 " ld %r2, 152(%r1) # restore TOC\n"
1127 #endif
1128 " ld %r14, 160(%r1) # restore R14\n"
1129 " ld %r15, 168(%r1) # restore R15\n"
1130 " ld %r16, 176(%r1) # restore R16\n"
1131 " ld %r17, 184(%r1) # restore R17\n"
1132 " ld %r18, 192(%r1) # restore R18\n"
1133 " ld %r19, 200(%r1) # restore R19\n"
1134 " ld %r20, 208(%r1) # restore R20\n"
1135 " ld %r21, 216(%r1) # restore R21\n"
1136 " ld %r22, 224(%r1) # restore R22\n"
1137 " ld %r23, 232(%r1) # restore R23\n"
1138 " ld %r24, 240(%r1) # restore R24\n"
1139 " ld %r25, 248(%r1) # restore R25\n"
1140 " ld %r26, 256(%r1) # restore R26\n"
1141 " ld %r27, 264(%r1) # restore R27\n"
1142 " ld %r28, 272(%r1) # restore R28\n"
1143 " ld %r29, 280(%r1) # restore R29\n"
1144 " ld %r30, 288(%r1) # restore R30\n"
1145 " ld %r31, 296(%r1) # restore R31\n"
1146 " # restore CR\n"
1147 " ld %r0, 304(%r1)\n"
1148 " mtcr %r0\n"
1149 " # restore LR\n"
1150 " ld %r0, 312(%r1)\n"
1151 " mtlr %r0\n"
1152 " # load PC\n"
1153 " ld %r12, 320(%r1)\n"
1154 " # restore CTR\n"
1155 " mtctr %r12\n"
1156 " # adjust stack\n"
1157 " addi %r1, %r1, 328\n"
1158 " # use third arg as return value after jump\n"
1159 " # use third arg as first arg in context function\n"
1160 " mr %r3, %r5\n"
1161 " # jump to context\n"
1162 " bctr\n"
1163 #if _CALL_ELF == 2
1164 " .size jump_fcontext, .-jump_fcontext\n"
1165 #else
1166 # ifdef _CALL_LINUX
1167 " .size .jump_fcontext, .-.L.jump_fcontext\n"
1168 # else
1169 " .size .jump_fcontext, .-.jump_fcontext\n"
1170 # endif
1171 #endif
1172 ".section .note.GNU-stack,\"\",%progbits\n"
1173 );
1174 
1175 #endif
1176 
1177 #if defined(LIBCONTEXT_PLATFORM_linux_ppc64) && defined(LIBCONTEXT_COMPILER_gcc)
1178 __asm (
1179 ".globl make_fcontext\n"
1180 #if _CALL_ELF == 2
1181 " .text\n"
1182 " .align 2\n"
1183 "make_fcontext:\n"
1184 " addis %r2, %r12, .TOC.-make_fcontext@ha\n"
1185 " addi %r2, %r2, .TOC.-make_fcontext@l\n"
1186 " .localentry make_fcontext, . - make_fcontext\n"
1187 #else
1188 " .section \".opd\",\"aw\"\n"
1189 " .align 3\n"
1190 "make_fcontext:\n"
1191 # ifdef _CALL_LINUX
1192 " .quad .L.make_fcontext,.TOC.@tocbase,0\n"
1193 " .type make_fcontext,@function\n"
1194 " .text\n"
1195 " .align 2\n"
1196 ".L.make_fcontext:\n"
1197 # else
1198 " .hidden .make_fcontext\n"
1199 " .globl .make_fcontext\n"
1200 " .quad .make_fcontext,.TOC.@tocbase,0\n"
1201 " .size make_fcontext,24\n"
1202 " .type .make_fcontext,@function\n"
1203 " .text\n"
1204 " .align 2\n"
1205 ".make_fcontext:\n"
1206 # endif
1207 #endif
1208 " # save return address into R6\n"
1209 " mflr %r6\n"
1210 " # first arg of make_fcontext() == top address of context-stack\n"
1211 " # shift address in R3 to lower 16 byte boundary\n"
1212 " clrrdi %r3, %r3, 4\n"
1213 " # reserve space for context-data on context-stack\n"
1214 " # including 64 byte of linkage + parameter area (R1 % 16 == 0)\n"
1215 " subi %r3, %r3, 392\n"
1216 " # third arg of make_fcontext() == address of context-function\n"
1217 " # entry point (ELFv2) or descriptor (ELFv1)\n"
1218 #if _CALL_ELF == 2
1219 " # save address of context-function entry point\n"
1220 " std %r5, 320(%r3)\n"
1221 #else
1222 " # save address of context-function entry point\n"
1223 " ld %r4, 0(%r5)\n"
1224 " std %r4, 320(%r3)\n"
1225 " # save TOC of context-function\n"
1226 " ld %r4, 8(%r5)\n"
1227 " std %r4, 152(%r3)\n"
1228 #endif
1229 " # load LR\n"
1230 " mflr %r0\n"
1231 " # jump to label 1\n"
1232 " bl 1f\n"
1233 "1:\n"
1234 " # load LR into R4\n"
1235 " mflr %r4\n"
1236 " # compute abs address of label finish\n"
1237 " addi %r4, %r4, finish - 1b\n"
1238 " # restore LR\n"
1239 " mtlr %r0\n"
1240 " # save address of finish as return-address for context-function\n"
1241 " # will be entered after context-function returns\n"
1242 " std %r4, 312(%r3)\n"
1243 " # restore return address from R6\n"
1244 " mtlr %r6\n"
1245 " blr # return pointer to context-data\n"
1246 "finish:\n"
1247 " # save return address into R0\n"
1248 " mflr %r0\n"
1249 " # save return address on stack, set up stack frame\n"
1250 " std %r0, 8(%r1)\n"
1251 " # allocate stack space, R1 % 16 == 0\n"
1252 " stdu %r1, -32(%r1)\n"
1253 " # exit code is zero\n"
1254 " li %r3, 0\n"
1255 " # exit application\n"
1256 " bl _exit\n"
1257 " nop\n"
1258 #if _CALL_ELF == 2
1259 " .size make_fcontext, .-make_fcontext\n"
1260 #else
1261 # ifdef _CALL_LINUX
1262 " .size .make_fcontext, .-.L.make_fcontext\n"
1263 # else
1264 " .size .make_fcontext, .-.make_fcontext\n"
1265 # endif
1266 #endif
1267 ".section .note.GNU-stack,\"\",%progbits\n"
1268 );
1269 
1270 #endif