fpc/rtl/riscv64/mathu.inc

150 lines
3.4 KiB
PHP

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