- Small patch to fix (delayed) loading of floating point state. Enables the special...
[reactos.git] / reactos / ntoskrnl / include / internal / i386 / intrin_i.h
1 #pragma once
2
3 #if defined(__GNUC__)
4
5 #define Ke386SetGlobalDescriptorTable(X) \
6 __asm__("lgdt %0\n\t" \
7 : /* no outputs */ \
8 : "m" (*X));
9
10 #define Ke386GetGlobalDescriptorTable(X) \
11 __asm__("sgdt %0\n\t" \
12 : "=m" (*X) \
13 : /* no input */ \
14 : "memory");
15
16 FORCEINLINE
17 VOID
18 Ke386FxStore(IN PFX_SAVE_AREA SaveArea)
19 {
20 asm volatile ("fxrstor (%0)" : : "r"(SaveArea));
21 }
22
23 FORCEINLINE
24 VOID
25 Ke386FxSave(IN PFX_SAVE_AREA SaveArea)
26 {
27 asm volatile ("fxsave (%0)" : : "r"(SaveArea));
28 }
29
30
31 FORCEINLINE
32 VOID
33 Ke386FnSave(IN PFLOATING_SAVE_AREA SaveArea)
34 {
35 asm volatile ("fnsave (%0); wait" : : "r"(SaveArea));
36 }
37
38 FORCEINLINE
39 VOID
40 Ke386SaveFpuState(IN PFX_SAVE_AREA SaveArea)
41 {
42 extern ULONG KeI386FxsrPresent;
43 if (KeI386FxsrPresent)
44 {
45 __asm__ __volatile__ ("fxsave %0\n" : : "m"(*SaveArea));
46 }
47 else
48 {
49 __asm__ __volatile__ ("fnsave %0\n wait\n" : : "m"(*SaveArea));
50 }
51 }
52
53 FORCEINLINE
54 USHORT
55 Ke386GetLocalDescriptorTable()
56 {
57 USHORT Ldt;
58 __asm__("sldt %0\n\t"
59 : "=m" (Ldt)
60 : /* no input */
61 : "memory");
62 return Ldt;
63 }
64
65 #define Ke386SetLocalDescriptorTable(X) \
66 __asm__("lldt %w0\n\t" \
67 : /* no outputs */ \
68 : "q" (X));
69
70 #define Ke386SetTr(X) __asm__ __volatile__("ltr %%ax" : :"a" (X));
71
72 FORCEINLINE
73 USHORT
74 Ke386GetTr(VOID)
75 {
76 USHORT Tr;
77 __asm__("str %0\n\t"
78 : "=m" (Tr));
79 return Tr;
80 }
81
82 #define _Ke386GetSeg(N) ({ \
83 unsigned int __d; \
84 __asm__("movl %%" #N ",%0\n\t" :"=r" (__d)); \
85 __d; \
86 })
87
88 #define _Ke386SetSeg(N,X) __asm__ __volatile__("movl %0,%%" #N : :"r" (X));
89
90 #define Ke386FnInit() __asm__("fninit\n\t");
91 #define Ke386ClearDirectionFlag() __asm__ __volatile__ ("cld")
92
93
94 //
95 // CR Macros
96 //
97 #define Ke386SetCr2(X) __asm__ __volatile__("movl %0,%%cr2" : :"r" (X));
98
99 //
100 // Segment Macros
101 //
102 #define Ke386GetSs() _Ke386GetSeg(ss)
103 #define Ke386GetFs() _Ke386GetSeg(fs)
104 #define Ke386GetDs() _Ke386GetSeg(ds)
105 #define Ke386GetEs() _Ke386GetSeg(es)
106 #define Ke386GetGs() _Ke386GetSeg(gs)
107 #define Ke386SetFs(X) _Ke386SetSeg(fs, X)
108 #define Ke386SetDs(X) _Ke386SetSeg(ds, X)
109 #define Ke386SetEs(X) _Ke386SetSeg(es, X)
110 #define Ke386SetSs(X) _Ke386SetSeg(ss, X)
111 #define Ke386SetGs(X) _Ke386SetSeg(gs, X)
112
113 #elif defined(_MSC_VER)
114
115 FORCEINLINE
116 VOID
117 Ke386FnInit(VOID)
118 {
119 __asm fninit;
120 }
121
122 FORCEINLINE
123 VOID
124 __sgdt(OUT PVOID Descriptor)
125 {
126 __asm
127 {
128 mov eax, Descriptor
129 sgdt [eax]
130 }
131 }
132
133 FORCEINLINE
134 VOID
135 __fxsave(OUT PFX_SAVE_AREA SaveArea)
136 {
137 __asm mov eax, SaveArea
138 __asm fxsave [eax]
139 }
140
141 FORCEINLINE
142 VOID
143 __fxrstor(IN PFX_SAVE_AREA SaveArea)
144 {
145 __asm mov eax, SaveArea
146 __asm fxrstor [eax]
147 }
148
149 FORCEINLINE
150 VOID
151 __fnsave(OUT PFLOATING_SAVE_AREA SaveArea)
152 {
153 __asm mov eax, SaveArea
154 __asm fnsave [eax]
155 __asm wait;
156 }
157
158 #define Ke386GetGlobalDescriptorTable __sgdt
159
160 FORCEINLINE
161 VOID
162 __lgdt(IN PVOID Descriptor)
163 {
164 __asm
165 {
166 mov eax, Descriptor
167 lgdt [eax]
168 }
169 }
170 #define Ke386SetGlobalDescriptorTable __lgdt
171
172 FORCEINLINE
173 USHORT
174 Ke386GetLocalDescriptorTable(VOID)
175 {
176 __asm sldt ax;
177 }
178
179 FORCEINLINE
180 VOID
181 Ke386SetLocalDescriptorTable(IN USHORT Descriptor)
182 {
183 __asm lldt Descriptor;
184 }
185
186 FORCEINLINE
187 VOID
188 Ke386SetTr(IN USHORT Tr)
189 {
190 __asm ltr Tr;
191 }
192
193 FORCEINLINE
194 USHORT
195 Ke386GetTr(VOID)
196 {
197 __asm str ax;
198 }
199
200 //
201 // CR Macros
202 //
203 FORCEINLINE
204 VOID
205 Ke386SetCr2(IN ULONG Value)
206 {
207 __asm mov eax, Value;
208 __asm mov cr2, eax;
209 }
210
211 //
212 // Segment Macros
213 //
214 FORCEINLINE
215 USHORT
216 Ke386GetSs(VOID)
217 {
218 __asm mov ax, ss;
219 }
220
221 FORCEINLINE
222 USHORT
223 Ke386GetFs(VOID)
224 {
225 __asm mov ax, fs;
226 }
227
228 FORCEINLINE
229 USHORT
230 Ke386GetDs(VOID)
231 {
232 __asm mov ax, ds;
233 }
234
235 FORCEINLINE
236 USHORT
237 Ke386GetEs(VOID)
238 {
239 __asm mov ax, es;
240 }
241
242 FORCEINLINE
243 VOID
244 Ke386SetSs(IN USHORT Value)
245 {
246 __asm mov ax, Value;
247 __asm mov ss, ax;
248 }
249
250 FORCEINLINE
251 VOID
252 Ke386SetFs(IN USHORT Value)
253 {
254 __asm mov ax, Value;
255 __asm mov fs, ax;
256 }
257
258 FORCEINLINE
259 VOID
260 Ke386SetDs(IN USHORT Value)
261 {
262 __asm mov ax, Value;
263 __asm mov ds, ax;
264 }
265
266 FORCEINLINE
267 VOID
268 Ke386SetEs(IN USHORT Value)
269 {
270 __asm mov ax, Value;
271 __asm mov es, ax;
272 }
273
274 FORCEINLINE
275 VOID
276 Ke386SetGs(IN USHORT Value)
277 {
278 __asm mov ax, Value;
279 __asm mov gs, ax;
280 }
281
282 extern ULONG KeI386FxsrPresent;
283
284 FORCEINLINE
285 VOID
286 Ke386SaveFpuState(IN PVOID SaveArea)
287 {
288 if (KeI386FxsrPresent)
289 {
290 __fxsave(SaveArea);
291 }
292 else
293 {
294 __fnsave(SaveArea);
295 }
296 }
297
298 #define Ke386FnSave __fnsave
299 #define Ke386FxSave __fxsave
300 // The name suggest, that the original author didn't understand what frstor means
301 #define Ke386FxStore __fxrstor
302
303
304 #else
305 #error Unknown compiler for inline assembler
306 #endif
307
308 /* EOF */