1 /* $Id: fpu.c,v 1.12 2003/12/30 18:52:04 fireball Exp $
4 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/ke/i386/fpu.c
23 * PURPOSE: Handles the FPU
24 * PROGRAMMER: David Welch (welch@mcmail.com)
29 /* INCLUDES *****************************************************************/
31 #include <ddk/ntddk.h>
32 #include <internal/ke.h>
33 #include <internal/mm.h>
34 #include <internal/ps.h>
37 #include <internal/debug.h>
39 /* GLOBALS *******************************************************************/
41 ULONG HardwareMathSupport
;
43 /* FUNCTIONS *****************************************************************/
48 unsigned short int status
;
51 HardwareMathSupport
= 0;
54 __asm__("movl %%cr0, %0\n\t" : "=a" (cr0_
));
59 __asm__("movl %0, %%cr0\n\t" : : "a" (cr0_
));
62 __asm__("fninit\n\t");
63 __asm__("fstsw %0\n\t" : "=a" (status
));
66 __asm__("movl %%cr0, %0\n\t" : "=a" (cr0_
));
67 /* Set the EM flag in CR0 so any FPU instructions cause a trap. */
69 __asm__("movl %0, %%cr0\n\t" :
73 /* fsetpm for i287, ignored by i387 */
74 __asm__(".byte 0xDB, 0xE4\n\t");
75 #elif defined(_MSC_VER)
78 cr0_
|= 0x22; /* Set NE and MP. */
79 cr0_
&= ~0x4; /* Clear EM */
91 __asm
or eax
, 4; /* Set the EM flag in CR0 so any FPU instructions cause a trap. */
95 /* fsetpm for i287, ignored by i387 */
96 __asm _emit
0xDB __asm _emit
0xe4
98 // __asm__(".byte 0xDB, 0xE4\n\t");
100 #error Unknown compiler for inline assembler
103 HardwareMathSupport
= 1;
106 /* This is a rather naive implementation of Ke(Save/Restore)FloatingPointState
107 which will not work for WDM drivers. Please feel free to improve */
109 #define FPU_STATE_SIZE 108
112 KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save
)
116 FpState
= ExAllocatePool(PagedPool
, FPU_STATE_SIZE
);
119 return STATUS_INSUFFICIENT_RESOURCES
;
121 *((PVOID
*) Save
) = FpState
;
123 #if defined(__GNUC__)
124 __asm__("fsave %0\n\t" : "=m" (*FpState
));
125 #elif defined(_MSC_VER)
126 __asm mov eax
, FpState
;
129 #error Unknown compiler for inline assembler
132 return STATUS_SUCCESS
;
136 KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save
)
138 char *FpState
= *((PVOID
*) Save
);
140 #if defined(__GNUC__)
141 __asm__("frstor %0\n\t" : "=m" (*FpState
));
142 #elif defined(_MSC_VER)
143 __asm mov eax
, FpState
;
146 #error Unknown compiler for inline assembler
151 return STATUS_SUCCESS
;