Revert tree-restructure attempt: r66583, r66582, r66581, r66578, sauf ntdll changes...
[reactos.git] / reactos / dll / win32 / kernel32 / client / i386 / fiber.S
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/thread/i386/fiber.S
5 * PURPOSE: Fiber context switch code for the x86 architecture
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * KJK::Hyperion <noog@libero.it>
8 */
9
10 #include <asm.inc>
11 #include <ks386.inc>
12
13 EXTERN _BaseThreadStartup@8:PROC
14
15 .code
16
17 PUBLIC _BaseFiberStartup@0
18 .PROC _BaseFiberStartup@0
19 /* Frame pointer is zeroed */
20 FPO 0, 0, 0, 0, 0, FRAME_FPO
21
22 /* Get the fiber data */
23 mov eax, fs:[TEB_FIBER_DATA]
24
25 push dword ptr [eax+FIBER_CONTEXT_EBX] /* Parameter */
26 push dword ptr [eax+FIBER_CONTEXT_EAX] /* Start Address */
27 call _BaseThreadStartup@8
28 .ENDP
29
30
31 PUBLIC _SwitchToFiber@4
32 _SwitchToFiber@4:
33 /* Get the TEB */
34 mov edx, fs:[TEB_SELF]
35
36 /* Get the Fiber */
37 mov eax, [edx+TEB_FIBER_DATA]
38
39 /* Save the non-volatile registers */
40 mov [eax+FIBER_CONTEXT_EBX], ebx
41 mov [eax+FIBER_CONTEXT_ESI], esi
42 mov [eax+FIBER_CONTEXT_EDI], edi
43 mov [eax+FIBER_CONTEXT_EBP], ebp
44
45 /* Check if we're to save FPU State */
46 cmp dword ptr [eax+FIBER_CONTEXT_FLAGS], CONTEXT_FULL OR CONTEXT_FLOATING_POINT
47 jnz NoFpuStateSave
48
49 /* Save the FPU State (Status and Control)*/
50 fstsw [eax+FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD]
51 fnstcw [eax+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
52
53 /* Check if the CPU supports SIMD MXCSR State Save */
54 cmp byte ptr ds:[PF_XMMI_INSTRUCTIONS_AVAILABLE], 1
55 jnz NoFpuStateSave
56 stmxcsr [eax+FIBER_CONTEXT_DR6]
57
58 NoFpuStateSave:
59
60 /* Save stack since we're not touching it anymore */
61 mov [eax+FIBER_CONTEXT_ESP], esp
62
63 /* Transfer some data from the TEB */
64 mov ecx, [edx+TEB_FLS_DATA]
65 mov [eax+FIBER_FLS_DATA], ecx
66 mov ecx, [edx+TEB_ACTIVATION_CONTEXT_STACK_POINTER]
67 mov [eax+FIBER_ACTIVATION_CONTEXT_STACK], ecx
68
69 /* Transfer some data related to the Stack */
70 mov ecx, [edx+TEB_EXCEPTION_LIST]
71 mov [eax+FIBER_EXCEPTION_LIST], ecx
72 mov ecx, [edx+TEB_STACK_LIMIT]
73 mov [eax+FIBER_STACK_LIMIT], ecx
74 mov ecx, [edx+TEB_GUARANTEED_STACK_BYTES]
75 mov [eax+FIBER_GUARANTEED_STACK_BYTES], ecx
76
77 /* Switch to the new fiber */
78 mov ecx, [esp+4]
79 mov [edx+TEB_FIBER_DATA], ecx
80
81 /* Switch Fiber Data */
82 mov esi, [ecx+FIBER_EXCEPTION_LIST]
83 mov [edx+TEB_EXCEPTION_LIST], esi
84 mov esi, [ecx+FIBER_STACK_BASE]
85 mov [edx+TEB_STACK_BASE], esi
86 mov esi, [ecx+FIBER_STACK_LIMIT]
87 mov [edx+TEB_STACK_LIMIT], esi
88 mov esi, [ecx+FIBER_DEALLOCATION_STACK]
89 mov [edx+TEB_DEALLOCATION_STACK], esi
90 mov esi, [ecx+FIBER_GUARANTEED_STACK_BYTES]
91 mov [edx+TEB_GUARANTEED_STACK_BYTES], esi
92 mov esi, [ecx+FIBER_ACTIVATION_CONTEXT_STACK]
93 mov [edx+TEB_ACTIVATION_CONTEXT_STACK_POINTER], esi
94
95 /* Restore FPU State */
96 cmp dword ptr [eax+FIBER_CONTEXT_FLAGS], CONTEXT_FULL OR CONTEXT_FLOATING_POINT
97 jnz NoFpuStateRestore
98
99 /* Check if the Status Word Changed */
100 mov esi, [eax+FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD]
101 cmp si, word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD]
102 jnz StatusWordChanged
103
104 /* Check if the Control Word Changed */
105 mov esi, [eax+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
106 cmp si, word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
107 jz ControlWordEqual
108
109 StatusWordChanged:
110
111 /* Load the new one */
112 mov word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_TAG_WORD], HEX(0FFFF)
113 fldenv [ecx+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
114
115 ControlWordEqual:
116
117 /* Load the new one */
118 cmp byte ptr ds:[PF_XMMI_INSTRUCTIONS_AVAILABLE], 1
119 jnz NoFpuStateRestore
120 ldmxcsr [ecx+FIBER_CONTEXT_DR6]
121
122 NoFpuStateRestore:
123
124 /* Restore non-volatile registers */
125 mov esi, [ecx+FIBER_CONTEXT_ESI]
126 mov edi, [ecx+FIBER_CONTEXT_EDI]
127 mov ebx, [ecx+FIBER_CONTEXT_EBX]
128 mov ebp, [ecx+FIBER_CONTEXT_EBP]
129 mov esp, [ecx+FIBER_CONTEXT_ESP]
130
131 /* Restore FLS Data */
132 mov eax, [ecx+FIBER_FLS_DATA]
133 mov [edx+TEB_FLS_DATA], eax
134
135 /* Jump to new fiber */
136 mov esp, [ecx+FIBER_CONTEXT_ESP]
137 ret 4
138
139
140 END
141 /* EOF */