|
@@ -0,0 +1,149 @@
|
|
|
|
+{
|
|
|
|
+ This file is part of the Free Pascal run time library.
|
|
|
|
+ Copyright (c) 2014 by Jonas Maebe
|
|
|
|
+ member of the Free Pascal development team
|
|
|
|
+
|
|
|
|
+ See the file COPYING.FPC, included in this distribution,
|
|
|
|
+ for details about the copyright.
|
|
|
|
+
|
|
|
|
+ This program is distributed in the hope that it will be useful,
|
|
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
+
|
|
|
|
+**********************************************************************}
|
|
|
|
+
|
|
|
|
+{$ifdef FPUFD}
|
|
|
|
+function GetRoundMode: TFPURoundingMode;
|
|
|
|
+ const
|
|
|
|
+ bits2rm: array[0..3] of TFPURoundingMode = (rmNearest,rmTruncate,rmDown,rmUp);
|
|
|
|
+ begin
|
|
|
|
+ result:=TFPURoundingMode(bits2rm[GetNativeFPUControlWord.rndmode])
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
|
|
|
|
+ const
|
|
|
|
+ rm2bits : array[TFPURoundingMode] of byte = (0,2,3,1);
|
|
|
|
+ var
|
|
|
|
+ cw: TNativeFPUControlWord;
|
|
|
|
+ begin
|
|
|
|
+ softfloat_rounding_mode:=RoundMode;
|
|
|
|
+ SetRoundMode:=GetRoundMode;
|
|
|
|
+ cw:=GetNativeFPUControlWord;
|
|
|
|
+ cw.rndmode:=rm2bits[RoundMode];
|
|
|
|
+ SetNativeFPUControlWord(cw);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function GetPrecisionMode: TFPUPrecisionMode;
|
|
|
|
+ begin
|
|
|
|
+ result:=pmDouble;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function SetPrecisionMode(const Precision: TFPUPrecisionMode): TFPUPrecisionMode;
|
|
|
|
+ begin
|
|
|
|
+ result:=pmDouble;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+const
|
|
|
|
+ fpu_nx = 1 shl 0;
|
|
|
|
+ fpu_uf = 1 shl 1;
|
|
|
|
+ fpu_of = 1 shl 2;
|
|
|
|
+ fpu_dz = 1 shl 3;
|
|
|
|
+ fpu_nv = 1 shl 4;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function GetExceptionMask: TFPUExceptionMask;
|
|
|
|
+ begin
|
|
|
|
+ Result:=softfloat_exception_mask;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
|
|
|
|
+ begin
|
|
|
|
+ Result:=softfloat_exception_mask;
|
|
|
|
+ { clear "exception happened" flags }
|
|
|
|
+ ClearExceptions(false);
|
|
|
|
+ softfloat_exception_mask:=Mask;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+procedure RaisePendingExceptions;
|
|
|
|
+ var
|
|
|
|
+ fflags : dword;
|
|
|
|
+ f: TFPUException;
|
|
|
|
+ begin
|
|
|
|
+ fflags:=GetNativeFPUControlWord.cw;
|
|
|
|
+ if (fflags and fpu_dz) <> 0 then
|
|
|
|
+ float_raise(exZeroDivide);
|
|
|
|
+ if (fflags and fpu_of) <> 0 then
|
|
|
|
+ float_raise(exOverflow);
|
|
|
|
+ if (fflags and fpu_uf) <> 0 then
|
|
|
|
+ float_raise(exUnderflow);
|
|
|
|
+ if (fflags and fpu_nv) <> 0 then
|
|
|
|
+ float_raise(exInvalidOp);
|
|
|
|
+ if (fflags and fpu_nx) <> 0 then
|
|
|
|
+ float_raise(exPrecision);
|
|
|
|
+ { now the soft float exceptions }
|
|
|
|
+ for f in softfloat_exception_flags do
|
|
|
|
+ float_raise(f);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+procedure ClearExceptions(RaisePending: Boolean);
|
|
|
|
+ var
|
|
|
|
+ cw: TNativeFPUControlWord;
|
|
|
|
+ begin
|
|
|
|
+ if raisepending then
|
|
|
|
+ RaisePendingExceptions;
|
|
|
|
+ softfloat_exception_flags:=[];
|
|
|
|
+ cw:=GetNativeFPUControlWord;
|
|
|
|
+ cw.cw:=0;
|
|
|
|
+ SetNativeFPUControlWord(cw);
|
|
|
|
+ end;
|
|
|
|
+{$else}
|
|
|
|
+function GetRoundMode: TFPURoundingMode;
|
|
|
|
+ begin
|
|
|
|
+ GetRoundMode:=softfloat_rounding_mode;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
|
|
|
|
+ begin
|
|
|
|
+ result:=softfloat_rounding_mode;
|
|
|
|
+ softfloat_rounding_mode:=RoundMode;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function GetPrecisionMode: TFPUPrecisionMode;
|
|
|
|
+ begin
|
|
|
|
+ result := pmDouble;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function SetPrecisionMode(const Precision: TFPUPrecisionMode): TFPUPrecisionMode;
|
|
|
|
+ begin
|
|
|
|
+ { does not apply }
|
|
|
|
+ result := pmDouble;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function GetExceptionMask: TFPUExceptionMask;
|
|
|
|
+ begin
|
|
|
|
+ Result:=softfloat_exception_mask;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
|
|
|
|
+ begin
|
|
|
|
+ Result:=softfloat_exception_mask;
|
|
|
|
+ softfloat_exception_mask:=Mask;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+procedure ClearExceptions(RaisePending: Boolean =true);
|
|
|
|
+ begin
|
|
|
|
+ softfloat_exception_flags:=[];
|
|
|
|
+ end;
|
|
|
|
+{$endif}
|