mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-08 16:28:24 +02:00
* correct masking of exceptions in genmath code
git-svn-id: trunk@5965 -
This commit is contained in:
parent
4f5c8cfe1f
commit
b3a1868ff0
@ -1206,6 +1206,8 @@ Procedure SysResetFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||
{ setup sse exceptions }
|
||||
ldmxcsr mxcsr
|
||||
end;
|
||||
softfloat_exception_flags:=0;
|
||||
softfloat_exception_mask:=float_flag_underflow or float_flag_inexact or float_flag_denormal;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -1240,7 +1240,8 @@ end;
|
||||
|
||||
procedure SysResetFpu;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||
begin
|
||||
{ nothing todo }
|
||||
softfloat_exception_flags:=0;
|
||||
softfloat_exception_mask:=float_flag_underflow or float_flag_inexact or float_flag_denormal;
|
||||
end;
|
||||
|
||||
{$endif FPC_SYSTEM_HAS_SYSRESETFPU}
|
||||
|
@ -100,6 +100,33 @@ type
|
||||
flag = byte;
|
||||
{$endif FPC_SYSTEM_HAS_flag}
|
||||
|
||||
{*
|
||||
-------------------------------------------------------------------------------
|
||||
Raises the exceptions specified by `flags'. Floating-point traps can be
|
||||
defined here if desired. It is currently not possible for such a trap
|
||||
to substitute a result value. If traps are not implemented, this routine
|
||||
should be simply `softfloat_exception_flags |= flags;'.
|
||||
-------------------------------------------------------------------------------
|
||||
*}
|
||||
procedure float_raise( i: shortint );
|
||||
Begin
|
||||
softfloat_exception_flags := softfloat_exception_flags or i;
|
||||
if ((softfloat_exception_flags and not(softfloat_exception_mask)) and float_flag_invalid) <> 0 then
|
||||
RunError(207)
|
||||
else
|
||||
if ((softfloat_exception_flags and not(softfloat_exception_mask)) and float_flag_divbyzero) <> 0 then
|
||||
RunError(200)
|
||||
else
|
||||
if ((softfloat_exception_flags and not(softfloat_exception_mask)) and float_flag_overflow) <> 0 then
|
||||
RunError(205)
|
||||
else
|
||||
if ((softfloat_exception_flags and not(softfloat_exception_mask)) and float_flag_underflow) <> 0 then
|
||||
RunError(206)
|
||||
else
|
||||
if ((softfloat_exception_flags and not(softfloat_exception_mask)) and float_flag_inexact) <> 0 then
|
||||
RunError(207);
|
||||
end;
|
||||
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_extractFloat64Frac0}
|
||||
Function extractFloat64Frac0(const a: float64): longint;
|
||||
@ -156,6 +183,8 @@ type
|
||||
aExp, shiftCount: smallint;
|
||||
aSig0, aSig1, absZ, aSigExtra: longint;
|
||||
z: longint;
|
||||
label
|
||||
invalid;
|
||||
Begin
|
||||
aSig1 := extractFloat64Frac1( a );
|
||||
aSig0 := extractFloat64Frac0( a );
|
||||
@ -165,7 +194,7 @@ type
|
||||
if 0<=shiftCount then
|
||||
Begin
|
||||
if (aExp=$7FF) and ((aSig0 or aSig1)<>0) then
|
||||
HandleError(207);
|
||||
goto invalid;
|
||||
shortShift64Left(aSig0 OR $00100000, aSig1, shiftCount, absZ, aSigExtra );
|
||||
End
|
||||
else
|
||||
@ -184,8 +213,19 @@ type
|
||||
else
|
||||
z:=absZ;
|
||||
if ((aSign<>0) xor (z<0)) AND (z<>0) then
|
||||
HandleError(207);
|
||||
float64_to_int32_round_to_zero := z;
|
||||
begin
|
||||
invalid:
|
||||
float_raise(float_flag_invalid);
|
||||
if (aSign <> 0) then
|
||||
float64_to_int32_round_to_zero:=$80000000
|
||||
else
|
||||
float64_to_int32_round_to_zero:=$7FFFFFFF;
|
||||
exit;
|
||||
end;
|
||||
if ( aSigExtra <> 0) then
|
||||
float_raise(float_flag_inexact);
|
||||
|
||||
float64_to_int32_round_to_zero := z;
|
||||
End;
|
||||
|
||||
|
||||
@ -207,9 +247,17 @@ type
|
||||
if aExp>=$43e then
|
||||
begin
|
||||
if int64(a)<>$C3E0000000000000 then
|
||||
HandleError(207);
|
||||
{ pascal doesn't know Inf for int64 }
|
||||
HandleError(207);
|
||||
begin
|
||||
float_raise(float_flag_invalid);
|
||||
if (aSign=0) or ((aExp=$7FF) and
|
||||
(aSig<>$0010000000000000 )) then
|
||||
begin
|
||||
result:=$7FFFFFFFFFFFFFFF;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
result:=$8000000000000000;
|
||||
exit;
|
||||
end;
|
||||
z:=aSig shl shiftCount;
|
||||
end
|
||||
@ -270,13 +318,14 @@ type
|
||||
Begin
|
||||
if ( a <> Float32($CF000000) ) then
|
||||
Begin
|
||||
float_raise( float_flag_invalid );
|
||||
if ( (aSign=0) or ( ( aExp = $FF ) and (aSig<>0) ) ) then
|
||||
Begin
|
||||
HandleError(207);
|
||||
float32_to_int32_round_to_zero:=$7fffffff;
|
||||
exit;
|
||||
end;
|
||||
End;
|
||||
HandleError(207);
|
||||
float32_to_int32_round_to_zero:=$80000000;
|
||||
exit;
|
||||
End
|
||||
else
|
||||
@ -561,8 +610,8 @@ type
|
||||
begin
|
||||
if( d <= 0.0 ) then
|
||||
begin
|
||||
if( d < 0.0 ) then
|
||||
HandleError(207);
|
||||
if d < 0.0 then
|
||||
d:=0/0;
|
||||
result := 0.0;
|
||||
end
|
||||
else
|
||||
@ -1005,7 +1054,10 @@ type
|
||||
Label Ldone;
|
||||
begin
|
||||
if( d <= 0.0 ) then
|
||||
HandleError(207);
|
||||
begin
|
||||
float_raise(float_flag_invalid);
|
||||
exit;
|
||||
end;
|
||||
d := frexp( d, e );
|
||||
|
||||
{ logarithm using log(x) = z + z**3 P(z)/Q(z),
|
||||
@ -1455,5 +1507,3 @@ function FPower10(val: Extended; Power: Longint): Extended;
|
||||
end;
|
||||
end;
|
||||
{$endif SUPPORT_EXTENDED}
|
||||
|
||||
|
||||
|
@ -24,8 +24,26 @@
|
||||
function GetSSECSR : dword;
|
||||
{$endif}
|
||||
|
||||
const
|
||||
{*
|
||||
-------------------------------------------------------------------------------
|
||||
Software IEC/IEEE floating-point exception flags.
|
||||
-------------------------------------------------------------------------------
|
||||
*}
|
||||
float_flag_invalid = 1;
|
||||
float_flag_denormal = 2;
|
||||
float_flag_divbyzero = 4;
|
||||
float_flag_overflow = 8;
|
||||
float_flag_underflow = 16;
|
||||
float_flag_inexact = 32;
|
||||
{ declarations of the math routines }
|
||||
|
||||
threadvar
|
||||
softfloat_exception_mask : Byte;
|
||||
softfloat_exception_flags : Byte;
|
||||
|
||||
procedure float_raise(i: shortint);
|
||||
|
||||
{$ifdef cpui386}
|
||||
{$define INTERNMATH}
|
||||
{$endif}
|
||||
|
@ -468,17 +468,6 @@ rounded down.
|
||||
float_round_up = 2;
|
||||
float_round_to_zero = 3;
|
||||
|
||||
{*
|
||||
-------------------------------------------------------------------------------
|
||||
Software IEC/IEEE floating-point exception flags.
|
||||
-------------------------------------------------------------------------------
|
||||
*}
|
||||
float_flag_invalid = 1;
|
||||
float_flag_divbyzero = 4;
|
||||
float_flag_overflow = 8;
|
||||
float_flag_underflow = 16;
|
||||
float_flag_inexact = 32;
|
||||
|
||||
{*
|
||||
-------------------------------------------------------------------------------
|
||||
Floating-point rounding mode and exception flags.
|
||||
@ -486,7 +475,6 @@ Floating-point rounding mode and exception flags.
|
||||
*}
|
||||
const
|
||||
float_rounding_mode : Byte = float_round_nearest_even;
|
||||
float_exception_flags : Byte = 0;
|
||||
|
||||
{*
|
||||
-------------------------------------------------------------------------------
|
||||
@ -505,31 +493,6 @@ implementation
|
||||
|
||||
|
||||
{$if not(defined(fpc_softfpu_interface))}
|
||||
{*
|
||||
-------------------------------------------------------------------------------
|
||||
Raises the exceptions specified by `flags'. Floating-point traps can be
|
||||
defined here if desired. It is currently not possible for such a trap
|
||||
to substitute a result value. If traps are not implemented, this routine
|
||||
should be simply `float_exception_flags |= flags;'.
|
||||
-------------------------------------------------------------------------------
|
||||
*}
|
||||
procedure float_raise( i: shortint );
|
||||
Begin
|
||||
float_exception_flags := float_exception_flags or i;
|
||||
if (float_exception_flags and float_flag_invalid) <> 0 then
|
||||
RunError(207)
|
||||
else
|
||||
if (float_exception_flags and float_flag_divbyzero) <> 0 then
|
||||
RunError(200)
|
||||
else
|
||||
if (float_exception_flags and float_flag_overflow) <> 0 then
|
||||
RunError(205)
|
||||
else
|
||||
if (float_exception_flags and float_flag_underflow) <> 0 then
|
||||
RunError(206);
|
||||
end;
|
||||
|
||||
|
||||
(*****************************************************************************)
|
||||
(*----------------------------------------------------------------------------*)
|
||||
(* Primitive arithmetic functions, including multi-word arithmetic, and *)
|
||||
@ -595,7 +558,7 @@ begin
|
||||
exit;
|
||||
end;
|
||||
if ( roundBits<>0 ) then
|
||||
float_exception_flags := float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags or float_flag_inexact;
|
||||
result:=z;
|
||||
end;
|
||||
|
||||
@ -658,7 +621,7 @@ begin
|
||||
result:=int64($7FFFFFFFFFFFFFFF);
|
||||
end;
|
||||
if ( absZ1<>0 ) then
|
||||
float_exception_flags := float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags or float_flag_inexact;
|
||||
result:=z;
|
||||
end;
|
||||
|
||||
@ -2169,7 +2132,7 @@ Function roundAndPackFloat32( zSign : Flag; zExp : Int16; zSig : Bits32 ) : floa
|
||||
End;
|
||||
End;
|
||||
if ( roundBits )<> 0 then
|
||||
float_exception_flags := float_flag_inexact OR float_exception_flags;
|
||||
softfloat_exception_flags := float_flag_inexact OR softfloat_exception_flags;
|
||||
zSig := ( zSig + roundIncrement ) shr 7;
|
||||
zSig := zSig AND not bits32( bits32( ( roundBits XOR $40 ) = 0 ) and roundNearestEven );
|
||||
if ( zSig = 0 ) then zExp := 0;
|
||||
@ -2432,7 +2395,7 @@ Procedure
|
||||
End;
|
||||
End;
|
||||
if ( zSig2 )<>0 then
|
||||
float_exception_flags := float_exception_flags OR float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags OR float_flag_inexact;
|
||||
if ( increment )<>0 then
|
||||
Begin
|
||||
add64( zSig0, zSig1, 0, 1, zSig0, zSig1 );
|
||||
@ -2522,7 +2485,7 @@ begin
|
||||
end
|
||||
end;
|
||||
if ( roundBits<>0 ) then
|
||||
float_exception_flags := float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags or float_flag_inexact;
|
||||
zSig := ( zSig + roundIncrement ) shr 10;
|
||||
zSig := zSig and not( ord( ( roundBits xor $200 ) = 0 ) and roundNearestEven );
|
||||
if ( zSig = 0 ) then
|
||||
@ -2695,7 +2658,7 @@ Function float32_to_int32( a : float32rec) : int32;compilerproc;
|
||||
z := aSig shr ( - shiftCount );
|
||||
End;
|
||||
if ( aSigExtra<>0 ) then
|
||||
float_exception_flags := float_exception_flags
|
||||
softfloat_exception_flags := softfloat_exception_flags
|
||||
or float_flag_inexact;
|
||||
roundingMode := float_rounding_mode;
|
||||
if ( roundingMode = float_round_nearest_even ) then
|
||||
@ -2766,8 +2729,8 @@ Function float32_to_int32_round_to_zero( a: Float32rec ): int32;compilerproc;
|
||||
if ( aExp <= $7E ) then
|
||||
Begin
|
||||
if ( aExp or aSig )<>0 then
|
||||
float_exception_flags :=
|
||||
float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags :=
|
||||
softfloat_exception_flags or float_flag_inexact;
|
||||
float32_to_int32_round_to_zero := 0;
|
||||
exit;
|
||||
End;
|
||||
@ -2775,8 +2738,8 @@ Function float32_to_int32_round_to_zero( a: Float32rec ): int32;compilerproc;
|
||||
z := aSig shr ( - shiftCount );
|
||||
if ( bits32 ( aSig shl ( shiftCount and 31 ) )<> 0 ) then
|
||||
Begin
|
||||
float_exception_flags :=
|
||||
float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags :=
|
||||
softfloat_exception_flags or float_flag_inexact;
|
||||
End;
|
||||
if ( aSign<>0 ) then z := - z;
|
||||
float32_to_int32_round_to_zero := z;
|
||||
@ -2859,8 +2822,8 @@ Function float32_round_to_int( a: float32rec): float32rec;compilerproc;
|
||||
float32_round_to_int:=a;
|
||||
exit;
|
||||
end;
|
||||
float_exception_flags
|
||||
:= float_exception_flags OR float_flag_inexact;
|
||||
softfloat_exception_flags
|
||||
:= softfloat_exception_flags OR float_flag_inexact;
|
||||
aSign := extractFloat32Sign( a.float32 );
|
||||
|
||||
case ( float_rounding_mode ) of
|
||||
@ -2912,7 +2875,7 @@ Function float32_round_to_int( a: float32rec): float32rec;compilerproc;
|
||||
End;
|
||||
z := z and not roundBitsMask;
|
||||
if ( z <> a.float32 ) then
|
||||
float_exception_flags := float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags or float_flag_inexact;
|
||||
float32_round_to_int.float32 := z;
|
||||
End;
|
||||
|
||||
@ -3820,7 +3783,7 @@ Begin
|
||||
exit;
|
||||
End;
|
||||
if ( aSigExtra <> 0) then
|
||||
float_exception_flags := float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags or float_flag_inexact;
|
||||
float64_to_int32 := z;
|
||||
End;
|
||||
|
||||
@ -3867,8 +3830,8 @@ Var
|
||||
Begin
|
||||
if ( aExp OR aSig0 OR aSig1 )<>0 then
|
||||
Begin
|
||||
float_exception_flags :=
|
||||
float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags :=
|
||||
softfloat_exception_flags or float_flag_inexact;
|
||||
End;
|
||||
float64_to_int32_round_to_zero := 0;
|
||||
exit;
|
||||
@ -3892,7 +3855,7 @@ Var
|
||||
exit;
|
||||
End;
|
||||
if ( aSigExtra <> 0) then
|
||||
float_exception_flags := float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags or float_flag_inexact;
|
||||
float64_to_int32_round_to_zero := z;
|
||||
End;
|
||||
|
||||
@ -4010,7 +3973,7 @@ Begin
|
||||
result := a;
|
||||
exit;
|
||||
End;
|
||||
float_exception_flags := float_exception_flags or
|
||||
softfloat_exception_flags := softfloat_exception_flags or
|
||||
float_flag_inexact;
|
||||
aSign := extractFloat64Sign( a );
|
||||
case ( float_rounding_mode ) of
|
||||
@ -4072,8 +4035,8 @@ Begin
|
||||
End;
|
||||
if ( ( z.low <> a.low ) OR ( z.high <> a.high ) ) then
|
||||
Begin
|
||||
float_exception_flags :=
|
||||
float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags :=
|
||||
softfloat_exception_flags or float_flag_inexact;
|
||||
End;
|
||||
result := z;
|
||||
End;
|
||||
@ -5453,7 +5416,7 @@ begin
|
||||
zExp := 0;
|
||||
roundBits := zSig0 and roundMask;
|
||||
if ( isTiny and roundBits ) float_raise( float_flag_underflow );
|
||||
if ( roundBits ) float_exception_flags |= float_flag_inexact;
|
||||
if ( roundBits ) softfloat_exception_flags |= float_flag_inexact;
|
||||
zSig0 += roundIncrement;
|
||||
if ( (sbits64) zSig0 < 0 ) zExp := 1;
|
||||
roundIncrement := roundMask + 1;
|
||||
@ -5464,7 +5427,7 @@ begin
|
||||
result:=packFloatx80( zSign, zExp, zSig0 );
|
||||
end;
|
||||
end;
|
||||
if ( roundBits ) float_exception_flags |= float_flag_inexact;
|
||||
if ( roundBits ) softfloat_exception_flags |= float_flag_inexact;
|
||||
zSig0 += roundIncrement;
|
||||
if ( zSig0 < roundIncrement ) begin
|
||||
++zExp;
|
||||
@ -5519,7 +5482,7 @@ begin
|
||||
shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
|
||||
zExp := 0;
|
||||
if ( isTiny and zSig1 ) float_raise( float_flag_underflow );
|
||||
if ( zSig1 ) float_exception_flags |= float_flag_inexact;
|
||||
if ( zSig1 ) softfloat_exception_flags |= float_flag_inexact;
|
||||
if ( roundNearestEven ) begin
|
||||
increment := ( (sbits64) zSig1 < 0 );
|
||||
end;
|
||||
@ -5540,7 +5503,7 @@ begin
|
||||
result:=packFloatx80( zSign, zExp, zSig0 );
|
||||
end;
|
||||
end;
|
||||
if ( zSig1 ) float_exception_flags |= float_flag_inexact;
|
||||
if ( zSig1 ) softfloat_exception_flags |= float_flag_inexact;
|
||||
if ( increment ) begin
|
||||
++zSig0;
|
||||
if ( zSig0 = 0 ) begin
|
||||
@ -5636,7 +5599,7 @@ begin
|
||||
goto invalid;
|
||||
end;
|
||||
else if ( aExp < $3FFF ) begin
|
||||
if ( aExp or aSig ) float_exception_flags or= float_flag_inexact;
|
||||
if ( aExp or aSig ) softfloat_exception_flags or= float_flag_inexact;
|
||||
result := 0;
|
||||
end;
|
||||
shiftCount := $403E - aExp;
|
||||
@ -5650,7 +5613,7 @@ begin
|
||||
result := aSign ? (sbits32) $80000000 : $7FFFFFFF;
|
||||
end;
|
||||
if ( ( aSig shl shiftCount ) <> savedASig ) begin
|
||||
float_exception_flags or= float_flag_inexact;
|
||||
softfloat_exception_flags or= float_flag_inexact;
|
||||
end;
|
||||
result := z;
|
||||
|
||||
@ -5729,12 +5692,12 @@ begin
|
||||
result := (sbits64) LIT64( $8000000000000000 );
|
||||
end;
|
||||
else if ( aExp < $3FFF ) begin
|
||||
if ( aExp or aSig ) float_exception_flags or= float_flag_inexact;
|
||||
if ( aExp or aSig ) softfloat_exception_flags or= float_flag_inexact;
|
||||
result := 0;
|
||||
end;
|
||||
z := aSig>>( - shiftCount );
|
||||
if ( (bits64) ( aSig shl ( shiftCount and 63 ) ) ) begin
|
||||
float_exception_flags or= float_flag_inexact;
|
||||
softfloat_exception_flags or= float_flag_inexact;
|
||||
end;
|
||||
if ( aSign ) z := - z;
|
||||
result := z;
|
||||
@ -5851,7 +5814,7 @@ begin
|
||||
and ( (bits64) ( extractFloatx80Frac( a ) shl 1 ) = 0 ) ) begin
|
||||
result := a;
|
||||
end;
|
||||
float_exception_flags or= float_flag_inexact;
|
||||
softfloat_exception_flags or= float_flag_inexact;
|
||||
aSign := extractFloatx80Sign( a );
|
||||
switch ( float_rounding_mode ) begin
|
||||
case float_round_nearest_even:
|
||||
@ -5892,7 +5855,7 @@ begin
|
||||
++z.high;
|
||||
z.low := LIT64( $8000000000000000 );
|
||||
end;
|
||||
if ( z.low <> a.low ) float_exception_flags or= float_flag_inexact;
|
||||
if ( z.low <> a.low ) softfloat_exception_flags or= float_flag_inexact;
|
||||
result := z;
|
||||
|
||||
end;
|
||||
@ -6789,7 +6752,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
if ( zSig2<>0 ) then
|
||||
float_exception_flags := float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags or float_flag_inexact;
|
||||
if ( increment<>0 ) then
|
||||
begin
|
||||
add128( zSig0, zSig1, 0, 1, zSig0, zSig1 );
|
||||
@ -6903,7 +6866,7 @@ begin
|
||||
else if ( aExp < $3FFF ) then
|
||||
begin
|
||||
if ( aExp or aSig0 )<>0 then
|
||||
float_exception_flags := float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags or float_flag_inexact;
|
||||
result := 0;
|
||||
exit;
|
||||
end;
|
||||
@ -6926,7 +6889,7 @@ begin
|
||||
end;
|
||||
if ( ( aSig0 shl shiftCount ) <> savedASig ) then
|
||||
begin
|
||||
float_exception_flags := float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags or float_flag_inexact;
|
||||
end;
|
||||
result := z;
|
||||
end;
|
||||
@ -7011,7 +6974,7 @@ begin
|
||||
and ( aSig1 < int64( $0002000000000000 ) ) ) then
|
||||
begin
|
||||
if ( aSig1<>0 ) then
|
||||
float_exception_flags := float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags or float_flag_inexact;
|
||||
end
|
||||
else begin
|
||||
float_raise( float_flag_invalid );
|
||||
@ -7027,7 +6990,7 @@ begin
|
||||
z := ( aSig0 shl shiftCount ) or ( aSig1>>( ( - shiftCount ) and 63 ) );
|
||||
if ( int64( aSig1 shl shiftCount )<>0 ) then
|
||||
begin
|
||||
float_exception_flags := float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags or float_flag_inexact;
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
@ -7035,7 +6998,7 @@ begin
|
||||
begin
|
||||
if ( aExp or aSig0 or aSig1 )<>0 then
|
||||
begin
|
||||
float_exception_flags := float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags or float_flag_inexact;
|
||||
end;
|
||||
result := 0;
|
||||
exit;
|
||||
@ -7044,7 +7007,7 @@ begin
|
||||
if ( (aSig1<>0)
|
||||
or ( (shiftCount<>0) and (int64( aSig0 shl ( shiftCount and 63 ) )<>0) ) ) then
|
||||
begin
|
||||
float_exception_flags := float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags or float_flag_inexact;
|
||||
end;
|
||||
end;
|
||||
if ( aSign<>0 ) then
|
||||
@ -7239,7 +7202,7 @@ begin
|
||||
result := a;
|
||||
exit;
|
||||
end;
|
||||
float_exception_flags := float_exception_flags or float_flag_inexact;
|
||||
softfloat_exception_flags := softfloat_exception_flags or float_flag_inexact;
|
||||
aSign := extractFloat128Sign( a );
|
||||
case float_rounding_mode of
|
||||
float_round_nearest_even:
|
||||
@ -7291,7 +7254,7 @@ begin
|
||||
z.high &= ~ roundBitsMask;
|
||||
end;
|
||||
if ( ( z.low <> a.low ) or ( z.high <> a.high ) ) begin
|
||||
float_exception_flags or= float_flag_inexact;
|
||||
softfloat_exception_flags or= float_flag_inexact;
|
||||
end;
|
||||
result := z;
|
||||
|
||||
|
@ -1237,14 +1237,19 @@ end;
|
||||
{$IFDEF MORPHOS}
|
||||
{ this is only required for MorphOS }
|
||||
{$define FPC_SYSTEM_HAS_SYSRESETFPU}
|
||||
procedure SysResetFPU;assembler;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||
var tmp: array[0..1] of dword;
|
||||
asm
|
||||
{ setting fpu to round to nearest mode }
|
||||
li r3,0
|
||||
stw r3,8(r1)
|
||||
stw r3,12(r1)
|
||||
lfd f1,8(r1)
|
||||
mtfsf 7,f1
|
||||
procedure SysResetFPU;$ifdef SYSTEMINLINE}inline;{$endif}
|
||||
var tmp: array[0..1] of dword;
|
||||
begin
|
||||
asm
|
||||
{ setting fpu to round to nearest mode }
|
||||
li r3,0
|
||||
stw r3,8(r1)
|
||||
stw r3,12(r1)
|
||||
lfd f1,8(r1)
|
||||
mtfsf 7,f1
|
||||
end;
|
||||
{ powerpc might use softfloat code }
|
||||
softfloat_exception_flags:=0;
|
||||
softfloat_exception_mask:=float_flag_underflow or float_flag_inexact or float_flag_denormal;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
@ -16,6 +16,9 @@
|
||||
unit System;
|
||||
interface
|
||||
|
||||
|
||||
{ $define SYSTEMEXCEPTIONDEBUG}
|
||||
|
||||
{$ifdef SYSTEMDEBUG}
|
||||
{$define SYSTEMEXCEPTIONDEBUG}
|
||||
{$endif SYSTEMDEBUG}
|
||||
|
@ -94,6 +94,7 @@ begin
|
||||
CtlWord:=Get8087CW;
|
||||
Set8087CW((CtlWord and $FFC0) or Byte(Longint(Mask)));
|
||||
SetSSECSR((GetSSECSR and $ffffe07f) or (dword(Mask) shl 7));
|
||||
softfloat_exception_mask:=dword(Mask);
|
||||
Result:=GetExceptionMask;
|
||||
end;
|
||||
|
||||
|
@ -592,22 +592,27 @@ const
|
||||
mxcsr : dword = MM_MaskUnderflow or MM_MaskPrecision or MM_MaskDenorm;
|
||||
|
||||
{$define FPC_SYSTEM_HAS_SYSRESETFPU}
|
||||
Procedure SysResetFPU;assembler;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||
asm
|
||||
Procedure SysResetFPU;
|
||||
begin
|
||||
asm
|
||||
{$ifndef WIN64}
|
||||
{ initialize fpu }
|
||||
fninit
|
||||
fwait
|
||||
{ initialize fpu }
|
||||
fninit
|
||||
fwait
|
||||
{$endif WIN64}
|
||||
{$ifdef FPC_PIC}
|
||||
movq fpucw@GOTPCREL(%rip),%rax
|
||||
fldcw (%rax)
|
||||
{ set sse exceptions }
|
||||
movq mxcsr@GOTPCREL(%rip),%rax
|
||||
ldmxcsr (%rax)
|
||||
movq fpucw@GOTPCREL(%rip),%rax
|
||||
fldcw (%rax)
|
||||
{ set sse exceptions }
|
||||
movq mxcsr@GOTPCREL(%rip),%rax
|
||||
ldmxcsr (%rax)
|
||||
{$else FPC_PIC}
|
||||
fldcw fpucw
|
||||
{ set sse exceptions }
|
||||
ldmxcsr mxcsr
|
||||
fldcw fpucw
|
||||
{ set sse exceptions }
|
||||
ldmxcsr mxcsr
|
||||
{$endif FPC_PIC}
|
||||
end ['RAX'];
|
||||
{ x86-64 might use softfloat code }
|
||||
softfloat_exception_flags:=0;
|
||||
softfloat_exception_mask:=float_flag_underflow or float_flag_inexact or float_flag_denormal;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user