1
2;           Copyright Oliver Kowalke 2009.
3;  Distributed under the Boost Software License, Version 1.0.
4;     (See accompanying file LICENSE_1_0.txt or copy at
5;           http://www.boost.org/LICENSE_1_0.txt)
6
7;  ----------------------------------------------------------------------------------
8;  |    0    |    1    |                                                            |
9;  ----------------------------------------------------------------------------------
10;  |   0x0   |   0x4   |                                                            |
11;  ----------------------------------------------------------------------------------
12;  |    <indicator>    |                                                            |
13;  ----------------------------------------------------------------------------------
14;  ----------------------------------------------------------------------------------
15;  |    2    |    3    |    4     |    5    |    6    |    7    |    8    |    9    |
16;  ----------------------------------------------------------------------------------
17;  |   0x8   |   0xc   |   0x10   |   0x14  |   0x18  |   0x1c  |   0x20  |   0x24  |
18;  ----------------------------------------------------------------------------------
19;  |                          SEE registers (XMM6-XMM15)                            |
20;  ----------------------------------------------------------------------------------
21;  ----------------------------------------------------------------------------------
22;  |   10    |   11    |    12    |    13   |    14   |    15   |    16   |    17   |
23;  ----------------------------------------------------------------------------------
24;  |   0x28  |  0x2c   |   0x30   |   0x34  |   0x38  |   0x3c  |   0x40  |   0x44  |
25;  ----------------------------------------------------------------------------------
26;  |                          SEE registers (XMM6-XMM15)                            |
27;  ----------------------------------------------------------------------------------
28;  ----------------------------------------------------------------------------------
29;  |    18   |    19   |    20   |    21    |    22   |    23   |    24   |    25   |
30;  ----------------------------------------------------------------------------------
31;  |   0x48  |   0x4c  |   0x50  |   0x54   |   0x58  |   0x5c  |  0x60   |   0x64  |
32;  ----------------------------------------------------------------------------------
33;  |                          SEE registers (XMM6-XMM15)                            |
34;  ----------------------------------------------------------------------------------
35;  ----------------------------------------------------------------------------------
36;  |    26   |    27   |    28    |   29    |    30   |    31   |    32   |    33   |
37;  ----------------------------------------------------------------------------------
38;  |   0x68  |   0x6c  |   0x70   |   0x74  |   0x78  |   0x7c  |   0x80  |   0x84  |
39;  ----------------------------------------------------------------------------------
40;  |                          SEE registers (XMM6-XMM15)                            |
41;  ----------------------------------------------------------------------------------
42;  ----------------------------------------------------------------------------------
43;  |    34    |   35   |    36    |    37   |    38   |    39   |    40   |    41   |
44;  ----------------------------------------------------------------------------------
45;  |   0x88   |  0x8c  |   0x90   |   0x94  |   0x98  |   0x9c  |   0xa0  |   0xa4  |
46;  ----------------------------------------------------------------------------------
47;  |                          SEE registers (XMM6-XMM15)                            |
48;  ----------------------------------------------------------------------------------
49;  ----------------------------------------------------------------------------------
50;  |    42   |    43   |    44    |    45   |    46   |    47   |    48   |    49   |
51;  ----------------------------------------------------------------------------------
52;  |   0xa8  |   0xac  |   0xb0   |   0xb4  |   0xb8  |   0xbc  |   0xc0  |   0xc4  |
53;  ----------------------------------------------------------------------------------
54;  | fc_mxcsr|fc_x87_cw|     <alignment>    |      fbr_strg     |      fc_dealloc   |
55;  ----------------------------------------------------------------------------------
56;  ----------------------------------------------------------------------------------
57;  |    50   |   51    |    52    |    53   |    54   |    55   |    56   |    57   |
58;  ----------------------------------------------------------------------------------
59;  |   0xc8  |  0xcc   |   0xd0   |   0xd4  |   0xd8  |   0xdc  |   0xe0  |   0xe4  |
60;  ----------------------------------------------------------------------------------
61;  |      limit        |       base         |      R12          |        R13        |
62;  ----------------------------------------------------------------------------------
63;  ----------------------------------------------------------------------------------
64;  |    58   |    59   |    60   |    61    |    62   |    63   |    64   |    65   |
65;  ----------------------------------------------------------------------------------
66;  |   0xe8  |   0xec  |   0xf0  |   0xf4   |   0xf8  |   0xfc  |  0x100  |  0x104  |
67;  ----------------------------------------------------------------------------------
68;  |        R14        |        R15         |       RDI         |       RSI         |
69;  ----------------------------------------------------------------------------------
70;  ----------------------------------------------------------------------------------
71;  |    66   |   67    |    68    |   69    |    70   |  71     |    72   |    73   |
72;  ----------------------------------------------------------------------------------
73;  |  0x108  |  0x10c  |  0x110   |  0x114  |  0x118  |  0x11c  |  0x120  |  0x124  |
74;  ----------------------------------------------------------------------------------
75;  |        RBX        |         RBP        |        RIP        |       EXIT        |
76;  ----------------------------------------------------------------------------------
77
78.code
79
80jump_fcontext PROC BOOST_CONTEXT_EXPORT FRAME
81    .endprolog
82
83    push  rbp  ; save RBP
84    push  rbx  ; save RBX
85    push  rsi  ; save RSI
86    push  rdi  ; save RDI
87    push  r15  ; save R15
88    push  r14  ; save R14
89    push  r13  ; save R13
90    push  r12  ; save R12
91
92    ; load NT_TIB
93    mov  r10,  gs:[030h]
94    ; save current stack base
95    mov  rax,  [r10+08h]
96    push  rax
97    ; save current stack limit
98    mov  rax, [r10+010h]
99    push  rax
100    ; save current deallocation stack
101    mov  rax, [r10+01478h]
102    push  rax
103    ; save fiber local storage
104    mov  rax, [r10+018h]
105    push  rax
106
107    ; prepare stack for FPU
108    lea rsp, [rsp-0a8h]
109
110    ; test for flag preserve_fpu
111    test  r9, r9
112    je  nxt1
113
114    ; save MMX control- and status-word
115    stmxcsr  [rsp+0a0h]
116    ; save x87 control-word
117    fnstcw  [rsp+0a4h]
118
119    ; save XMM storage
120    movaps  [rsp], xmm6
121    movaps  [rsp+010h], xmm7
122    movaps  [rsp+020h], xmm8
123    movaps  [rsp+030h], xmm9
124    movaps  [rsp+040h], xmm10
125    movaps  [rsp+050h], xmm11
126    movaps  [rsp+060h], xmm12
127    movaps  [rsp+070h], xmm13
128    movaps  [rsp+080h], xmm14
129    movaps  [rsp+090h], xmm15
130
131nxt1:
132    ; set R10 to zero
133    xor  r10, r10
134    ; set indicator
135    push  r10
136
137    ; store RSP (pointing to context-data) in RCX
138    mov  [rcx], rsp
139
140    ; restore RSP (pointing to context-data) from RDX
141    mov  rsp, rdx
142
143    ; load indicator
144    pop  r10
145
146    ; test for flag preserve_fpu
147    test  r9, r9
148    je  nxt2
149
150    ; restore MMX control- and status-word
151    ldmxcsr  [rsp+0a0h]
152    ; save x87 control-word
153    fldcw   [rsp+0a4h]
154
155    ; restore XMM storage
156    movaps  xmm6, [rsp]
157    movaps  xmm7, [rsp+010h]
158    movaps  xmm8, [rsp+020h]
159    movaps  xmm9, [rsp+030h]
160    movaps  xmm10, [rsp+040h]
161    movaps  xmm11, [rsp+050h]
162    movaps  xmm12, [rsp+060h]
163    movaps  xmm13, [rsp+070h]
164    movaps  xmm14, [rsp+080h]
165    movaps  xmm15, [rsp+090h]
166
167nxt2:
168    ; set offset of stack
169    mov  rcx, 0a8h
170
171    ; test for indicator
172    test  r10, r10
173    je  nxt3
174
175    add  rcx, 08h
176
177nxt3:
178    ; prepare stack for FPU
179    lea rsp, [rsp+rcx]
180
181    ; load NT_TIB
182    mov  r10, gs:[030h]
183    ; restore fiber local storage
184    pop  rax
185    mov  [r10+018h], rax
186    ; restore deallocation stack
187    pop  rax
188    mov  [r10+01478h], rax
189    ; restore stack limit
190    pop  rax
191    mov  [r10+010h], rax
192    ; restore stack base
193    pop  rax
194    mov  [r10+08h], rax
195
196    pop  r12  ; restore R12
197    pop  r13  ; restore R13
198    pop  r14  ; restore R14
199    pop  r15  ; restore R15
200    pop  rdi  ; restore RDI
201    pop  rsi  ; restore RSI
202    pop  rbx  ; restore RBX
203    pop  rbp  ; restore RBP
204
205    ; restore return-address
206    pop  r10
207
208    ; use third arg as return-value after jump
209    mov  rax, r8
210    ; use third arg as first arg in context function
211    mov  rcx, r8
212
213    ; indirect jump to context
214    jmp  r10
215jump_fcontext ENDP
216END
217