Fix the fix
[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 FUNC _BaseFiberStartup@0
19 FPO 0, 0, 0, 0, 0, FRAME_FPO
20
21 /* Note that EBP is already zeroed for us during fiber creation */
22
23 /* Get the fiber data */
24 mov eax, fs:[TEB_FIBER_DATA]
25
26 /* Start the thread with our parameters */
27 push dword ptr [eax+FIBER_CONTEXT_EBX]
28 push dword ptr [eax+FIBER_CONTEXT_EAX]
29 push 0
30 jmp _BaseThreadStartup@8
31
32 ENDFUNC
33
34
35 PUBLIC _SwitchToFiber@4
36 FUNC _SwitchToFiber@4
37 FPO 0, 0, 0, 0, 0, FRAME_FPO
38
39 /* Get the TEB */
40 mov edx, fs:[TEB_SELF]
41
42 /* Get the Fiber */
43 mov eax, [edx+TEB_FIBER_DATA]
44
45 /* Save the non-volatile registers */
46 mov [eax+FIBER_CONTEXT_EBX], ebx
47 mov [eax+FIBER_CONTEXT_ESI], esi
48 mov [eax+FIBER_CONTEXT_EDI], edi
49 mov [eax+FIBER_CONTEXT_EBP], ebp
50
51 /* Check if we're to save FPU State */
52 cmp dword ptr [eax+FIBER_CONTEXT_FLAGS], CONTEXT_FULL OR CONTEXT_FLOATING_POINT
53 jnz NoFpuStateSave
54
55 /* Save the FPU State (Status and Control)*/
56 fstsw [eax+FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD]
57 fnstcw [eax+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
58
59 /* Check if the CPU supports SIMD MXCSR State Save */
60 cmp byte ptr ds:[USER_SHARED_DATA + USER_SHARED_DATA_PROCESSOR_FEATURES + PF_XMMI_INSTRUCTIONS_AVAILABLE], 1
61 jnz NoFpuStateSave
62 stmxcsr [eax+FIBER_CONTEXT_DR6]
63
64 NoFpuStateSave:
65
66 /* Save stack since we're not touching it anymore */
67 mov [eax+FIBER_CONTEXT_ESP], esp
68
69 /* Transfer some data from the TEB */
70 mov ecx, [edx+TEB_FLS_DATA]
71 mov [eax+FIBER_FLS_DATA], ecx
72 mov ecx, [edx+TEB_ACTIVATION_CONTEXT_STACK_POINTER]
73 mov [eax+FIBER_ACTIVATION_CONTEXT_STACK], ecx
74
75 /* Transfer some data related to the Stack */
76 mov ecx, [edx+TEB_EXCEPTION_LIST]
77 mov [eax+FIBER_EXCEPTION_LIST], ecx
78 mov ecx, [edx+TEB_STACK_LIMIT]
79 mov [eax+FIBER_STACK_LIMIT], ecx
80 mov ecx, [edx+TEB_GUARANTEED_STACK_BYTES]
81 mov [eax+FIBER_GUARANTEED_STACK_BYTES], ecx
82
83 /* Switch to the new fiber */
84 mov ecx, [esp+4]
85 mov [edx+TEB_FIBER_DATA], ecx
86
87 /* Switch Fiber Data */
88 mov esi, [ecx+FIBER_EXCEPTION_LIST]
89 mov [edx+TEB_EXCEPTION_LIST], esi
90 mov esi, [ecx+FIBER_STACK_BASE]
91 mov [edx+TEB_STACK_BASE], esi
92 mov esi, [ecx+FIBER_STACK_LIMIT]
93 mov [edx+TEB_STACK_LIMIT], esi
94 mov esi, [ecx+FIBER_DEALLOCATION_STACK]
95 mov [edx+TEB_DEALLOCATION_STACK], esi
96 mov esi, [ecx+FIBER_GUARANTEED_STACK_BYTES]
97 mov [edx+TEB_GUARANTEED_STACK_BYTES], esi
98 mov esi, [ecx+FIBER_ACTIVATION_CONTEXT_STACK]
99 mov [edx+TEB_ACTIVATION_CONTEXT_STACK_POINTER], esi
100
101 /* Restore FPU State */
102 cmp dword ptr [eax+FIBER_CONTEXT_FLAGS], CONTEXT_FULL OR CONTEXT_FLOATING_POINT
103 jnz NoFpuStateRestore
104
105 /* Check if the Status Word Changed */
106 mov esi, [eax+FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD]
107 cmp si, word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_STATUS_WORD]
108 jnz StatusWordChanged
109
110 /* Check if the Control Word Changed */
111 mov esi, [eax+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
112 cmp si, word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
113 jz ControlWordEqual
114
115 StatusWordChanged:
116
117 /* Load the new one */
118 mov word ptr [ecx+FIBER_CONTEXT_FLOAT_SAVE_TAG_WORD], HEX(FFFF)
119 fldenv [ecx+FIBER_CONTEXT_FLOAT_SAVE_CONTROL_WORD]
120
121 ControlWordEqual:
122
123 /* Load the new one */
124 cmp byte ptr ds:[USER_SHARED_DATA + USER_SHARED_DATA_PROCESSOR_FEATURES + PF_XMMI_INSTRUCTIONS_AVAILABLE], 1
125 jnz NoFpuStateRestore
126 ldmxcsr [ecx+FIBER_CONTEXT_DR6]
127
128 NoFpuStateRestore:
129
130 /* Restore non-volatile registers */
131 mov esi, [ecx+FIBER_CONTEXT_ESI]
132 mov edi, [ecx+FIBER_CONTEXT_EDI]
133 mov ebx, [ecx+FIBER_CONTEXT_EBX]
134 mov ebp, [ecx+FIBER_CONTEXT_EBP]
135 mov esp, [ecx+FIBER_CONTEXT_ESP]
136
137 /* Restore FLS Data */
138 mov eax, [ecx+FIBER_FLS_DATA]
139 mov [edx+TEB_FLS_DATA], eax
140
141 /* Jump to new fiber */
142 mov esp, [ecx+FIBER_CONTEXT_ESP]
143 ret 4
144
145 ENDFUNC
146
147 END
148 /* EOF */