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(VOID)
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 */
309