Forward compatibility: build relative-base link libraries where needed
[AROS.git] / arch / x86_64-all / exec / stackswap.S
blob9134dfeebdb9318103e11c86bf2d4c7a01fd83e2
1 #include <aros/x86_64/asm.h>
2 #include <aros/config.h>
4                 .text
5                 .align  16
6                 .globl  AROS_SLIB_ENTRY(StackSwap, Exec, 122)
7                 .type   AROS_SLIB_ENTRY(StackSwap, Exec, 122), @function
8                 
9 AROS_SLIB_ENTRY(StackSwap, Exec, 122):
10                 /* struct StackSwap is %rdi */
11                 /* SysBase is %rsi */
12                 
13                 pushq   %rbx
14                 
15                 /* StackSwap -> %rbx */
16                 movq    %rdi, %rbx
17                 
18                 /* Disable interrupts */
19                 pushq   %rsi
20                 movq    %rsi, %rdi      /* Put SysBase into rdi (first argument) */
21                 call    *Disable(%rsi)
22                 popq    %rsi
24                 movq    ThisTask(%rsi), %rax
26                 /* Exchange tc_SPLower */
27                 movq    tc_SPLower(%rax), %rcx
28                 xchgq   %rcx, stk_Lower(%rbx)
29                 movq    %rcx, tc_SPLower(%rax)
31                 /* Exchange tc_SPUpper */
32                 movq    tc_SPUpper(%rax), %rcx
33                 xchgq   %rcx, stk_Upper(%rbx)
34                 movq    %rcx, tc_SPUpper(%rax)
36                 movb    tc_Flags(%rax), %cl
37                 test    $TF_STACKCHK, %cl
38                 je      noStackSnoop
40                 /* Fill [stk_Lower .. stk_Pointer - 16] with 0xE1 */
42                 /* Destination register = %rdi = NEW SPLower.
43                    Which was already swapped above, so to be found
44                    in task->tc_SPLower */
45                 movq    tc_SPLower(%rax), %rdi
47                 /* %rcx = count register = NEW SP register - NEW SP_Lower - 16 */
48                 movq    stk_Pointer(%rbx), %rcx
49                 subq    $16, %rcx
50                 subq    %rdi, %rcx
52                 /* byte value to store */
53                 movb    $0xE1, %al
55                 /* direction to store: forward */
56                 cld
58                 /* do the store operation: put %rcx times %al into memory starting at %rdi. */
59                 rep
60                 stosb
62 noStackSnoop:
63                 /* StackSwap -> %rdi */
64                 movq    %rbx, %rdi
65                 popq    %rbx
66                 
67                 /* Get the return address */
68                 popq    %rax
69                 
70                 /* Restore *NEW* stack pointer */
71                 xchgq   %rsp, stk_Pointer(%rdi)
72                 
73                 pushq   %rdi
74                 pushq   %rax
75                 movq    %rsi, %rdi
76                 call    *Enable(%rsi)
77                 popq    %rax
78                 popq    %rdi
79                 
80                 jmpq    *%rax
81