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