123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- {
- 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}
|