diff --git a/rtl/i8086/i8086.inc b/rtl/i8086/i8086.inc index 69cf8e6ef2..f2de1c27b8 100644 --- a/rtl/i8086/i8086.inc +++ b/rtl/i8086/i8086.inc @@ -107,3 +107,56 @@ begin runerror(304); end; +{**************************************************************************** + FPU +****************************************************************************} + +const + { Internal constants for use in system unit } + FPU_Invalid = 1; + FPU_Denormal = 2; + FPU_DivisionByZero = 4; + FPU_Overflow = 8; + FPU_Underflow = $10; + FPU_StackUnderflow = $20; + FPU_StackOverflow = $40; + FPU_ExceptionMask = $ff; + + { use Default8087CW instead + fpucw : word = $1300 or FPU_StackUnderflow or FPU_Underflow or FPU_Denormal; + } + + +{$define FPC_SYSTEM_HAS_SYSINITFPU} +Procedure SysInitFPU; + var + { these locals are so we don't have to hack pic code in the assembler } + localmxcsr: dword; + localfpucw: word; + begin + localfpucw:=Default8087CW; + asm + fninit + fldcw localfpucw + fwait + end; + softfloat_exception_mask:=float_flag_underflow or float_flag_inexact or float_flag_denormal; + end; + + +{$define FPC_SYSTEM_HAS_SYSRESETFPU} +Procedure SysResetFPU; + var + { these locals are so we don't have to hack pic code in the assembler } + localmxcsr: dword; + localfpucw: word; + begin + localfpucw:=Default8087CW; + asm + fninit + fwait + fldcw localfpucw + end; + softfloat_exception_flags:=0; + end; + diff --git a/rtl/i8086/math.inc b/rtl/i8086/math.inc index d067c2e164..b60613cc52 100644 --- a/rtl/i8086/math.inc +++ b/rtl/i8086/math.inc @@ -15,6 +15,34 @@ **********************************************************************} {$asmmode intel} + +{**************************************************************************** + FPU Control word + ****************************************************************************} + + procedure Set8087CW(cw:word); + begin + { pic-safe ; cw will not be a regvar because it's accessed from } + { assembler } + default8087cw:=cw; + asm + fnclex + fldcw cw + end; + end; + + + function Get8087CW:word;assembler; + asm + push bp + mov bp, sp + push ax + fnstcw [bp - 2] + pop ax + mov sp, bp + pop bp + end; + {**************************************************************************** EXTENDED data type routines ****************************************************************************} diff --git a/rtl/inc/mathh.inc b/rtl/inc/mathh.inc index 60356d2e6f..7967ef1c10 100644 --- a/rtl/inc/mathh.inc +++ b/rtl/inc/mathh.inc @@ -14,14 +14,16 @@ { i386 FPU Controlword } -{$if defined(cpui386) or defined(cpux86_64)} +{$if defined(cpui8086) or defined(cpui386) or defined(cpux86_64)} const Default8087CW : word = $1332; procedure Set8087CW(cw:word); function Get8087CW:word; + {$ifndef cpui8086} procedure SetSSECSR(w : dword); function GetSSECSR : dword; + {$endif not cpui8086} {$endif} const diff --git a/rtl/msdos/system.pp b/rtl/msdos/system.pp index 0e9c06487b..baa6ca2f99 100644 --- a/rtl/msdos/system.pp +++ b/rtl/msdos/system.pp @@ -214,6 +214,7 @@ end; begin StackLength := CheckInitialStkLen(InitialStkLen); StackBottom := __stkbottom; + SysInitFPU; { To be set if this is a GUI or console application } IsConsole := TRUE; { To be set if this is a library and not a program }