3a2664ba5b4fe5b1033bf19d556f1748bd116de9
[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 VOID
55 Ke386LoadFpuState(IN PFX_SAVE_AREA SaveArea)
56 {
57 extern ULONG KeI386FxsrPresent;
58 if (KeI386FxsrPresent)
59 {
60 __asm__ __volatile__ ("fxrstor %0\n" : "=m"(SaveArea) : );
61 }
62 else
63 {
64 __asm__ __volatile__ (".globl _FrRestore\n _FrRestore: \n frstor %0\n wait\n" : "=m"(SaveArea) : );
65 }
66 }
67
68 FORCEINLINE
69 USHORT
70 Ke386GetLocalDescriptorTable()
71 {
72 USHORT Ldt;
73 __asm__("sldt %0\n\t"
74 : "=m" (Ldt)
75 : /* no input */
76 : "memory");
77 return Ldt;
78 }
79
80 #define Ke386SetLocalDescriptorTable(X) \
81 __asm__("lldt %w0\n\t" \
82 : /* no outputs */ \
83 : "q" (X));
84
85 #define Ke386SetTr(X) __asm__ __volatile__("ltr %%ax" : :"a" (X));
86
87 FORCEINLINE
88 USHORT
89 Ke386GetTr(VOID)
90 {
91 USHORT Tr;
92 __asm__("str %0\n\t"
93 : "=m" (Tr));
94 return Tr;
95 }
96
97 #define _Ke386GetSeg(N) ({ \
98 unsigned int __d; \
99 __asm__("movl %%" #N ",%0\n\t" :"=r" (__d)); \
100 __d; \
101 })
102
103 #define _Ke386SetSeg(N,X) __asm__ __volatile__("movl %0,%%" #N : :"r" (X));
104
105 #define Ke386FnInit() __asm__("fninit\n\t");
106 #define Ke386ClearDirectionFlag() __asm__ __volatile__ ("cld")
107
108
109 //
110 // CR Macros
111 //
112 #define Ke386SetCr2(X) __asm__ __volatile__("movl %0,%%cr2" : :"r" (X));
113
114 //
115 // Segment Macros
116 //
117 #define Ke386GetSs() _Ke386GetSeg(ss)
118 #define Ke386GetFs() _Ke386GetSeg(fs)
119 #define Ke386GetDs() _Ke386GetSeg(ds)
120 #define Ke386GetEs() _Ke386GetSeg(es)
121 #define Ke386GetGs() _Ke386GetSeg(gs)
122 #define Ke386SetFs(X) _Ke386SetSeg(fs, X)
123 #define Ke386SetDs(X) _Ke386SetSeg(ds, X)
124 #define Ke386SetEs(X) _Ke386SetSeg(es, X)
125 #define Ke386SetSs(X) _Ke386SetSeg(ss, X)
126 #define Ke386SetGs(X) _Ke386SetSeg(gs, X)
127
128 #elif defined(_MSC_VER)
129
130 FORCEINLINE
131 VOID
132 Ke386FnInit(VOID)
133 {
134 __asm fninit;
135 }
136
137 FORCEINLINE
138 VOID
139 __sgdt(OUT PVOID Descriptor)
140 {
141 __asm
142 {
143 mov eax, Descriptor
144 sgdt [eax]
145 }
146 }
147
148 FORCEINLINE
149 VOID
150 __fxsave(OUT PFX_SAVE_AREA SaveArea)
151 {
152 __asm mov eax, SaveArea
153 __asm fxsave [eax]
154 }
155
156 FORCEINLINE
157 VOID
158 __fxrstor(IN PFX_SAVE_AREA SaveArea)
159 {
160 __asm mov eax, SaveArea
161 __asm fxrstor [eax]
162 }
163
164 FORCEINLINE
165 VOID
166 __fnsave(OUT PFLOATING_SAVE_AREA SaveArea)
167 {
168 __asm mov eax, SaveArea
169 __asm fnsave [eax]
170 __asm wait;
171 }
172
173 #define Ke386GetGlobalDescriptorTable __sgdt
174
175 FORCEINLINE
176 VOID
177 __lgdt(IN PVOID Descriptor)
178 {
179 __asm
180 {
181 mov eax, Descriptor
182 lgdt [eax]
183 }
184 }
185 #define Ke386SetGlobalDescriptorTable __lgdt
186
187 FORCEINLINE
188 USHORT
189 Ke386GetLocalDescriptorTable(VOID)
190 {
191 __asm sldt ax;
192 }
193
194 FORCEINLINE
195 VOID
196 Ke386SetLocalDescriptorTable(IN USHORT Descriptor)
197 {
198 __asm lldt Descriptor;
199 }
200
201 FORCEINLINE
202 VOID
203 Ke386SetTr(IN USHORT Tr)
204 {
205 __asm ltr Tr;
206 }
207
208 FORCEINLINE
209 USHORT
210 Ke386GetTr(VOID)
211 {
212 __asm str ax;
213 }
214
215 //
216 // CR Macros
217 //
218 FORCEINLINE
219 VOID
220 Ke386SetCr2(IN ULONG Value)
221 {
222 __asm mov eax, Value;
223 __asm mov cr2, eax;
224 }
225
226 //
227 // Segment Macros
228 //
229 FORCEINLINE
230 USHORT
231 Ke386GetSs(VOID)
232 {
233 __asm mov ax, ss;
234 }
235
236 FORCEINLINE
237 USHORT
238 Ke386GetFs(VOID)
239 {
240 __asm mov ax, fs;
241 }
242
243 FORCEINLINE
244 USHORT
245 Ke386GetDs(VOID)
246 {
247 __asm mov ax, ds;
248 }
249
250 FORCEINLINE
251 USHORT
252 Ke386GetEs(VOID)
253 {
254 __asm mov ax, es;
255 }
256
257 FORCEINLINE
258 VOID
259 Ke386SetSs(IN USHORT Value)
260 {
261 __asm mov ax, Value;
262 __asm mov ss, ax;
263 }
264
265 FORCEINLINE
266 VOID
267 Ke386SetFs(IN USHORT Value)
268 {
269 __asm mov ax, Value;
270 __asm mov fs, ax;
271 }
272
273 FORCEINLINE
274 VOID
275 Ke386SetDs(IN USHORT Value)
276 {
277 __asm mov ax, Value;
278 __asm mov ds, ax;
279 }
280
281 FORCEINLINE
282 VOID
283 Ke386SetEs(IN USHORT Value)
284 {
285 __asm mov ax, Value;
286 __asm mov es, ax;
287 }
288
289 FORCEINLINE
290 VOID
291 Ke386SetGs(IN USHORT Value)
292 {
293 __asm mov ax, Value;
294 __asm mov gs, ax;
295 }
296
297 extern ULONG KeI386FxsrPresent;
298
299 FORCEINLINE
300 VOID
301 Ke386SaveFpuState(IN PVOID SaveArea)
302 {
303 if (KeI386FxsrPresent)
304 {
305 __fxsave(SaveArea);
306 }
307 else
308 {
309 __fnsave(SaveArea);
310 }
311 }
312
313 #define Ke386FnSave __fnsave
314 #define Ke386FxSave __fxsave
315 // The name suggest, that the original author didn't understand what frstor means
316 #define Ke386FxStore __fxrstor
317
318
319 #else
320 #error Unknown compiler for inline assembler
321 #endif
322
323 /* EOF */