Fix ARM FPU exception masks

This corrects the handling of exception masks and ARM VFP
implementations. The old code enable the exception when it was present
in the mask. So in fact it did the contrary of what it was supposed to
do.

VFP-Support is currently broken, this patch at least allows to build a
working VFP-native compiler. But the full build still breaks because of
some compiler options not properly beeing passed down to packages/ which
results in:

"Trying to use a unit which was compiled with a different FPU mode"

because somehow OPT="-Cfvfpv2" did not get passed down.

git-svn-id: trunk@21952 -
This commit is contained in:
masta 2012-07-23 07:26:57 +00:00
parent 109eb8bf75
commit 386738a7c3

View File

@ -132,17 +132,17 @@ end;
function ConvertExceptionMask(em: dword): TFPUExceptionMask;
begin
Result:=[];
if em and _EM_INVALID <> 0 then
if em and _EM_INVALID = 0 then
Result:=Result + [exInvalidOp];
if em and _EM_DENORMAL <> 0 then
if em and _EM_DENORMAL = 0 then
Result:=Result + [exDenormalized];
if em and _EM_ZERODIVIDE <> 0 then
if em and _EM_ZERODIVIDE = 0 then
Result:=Result + [exZeroDivide];
if em and _EM_OVERFLOW <> 0 then
if em and _EM_OVERFLOW = 0 then
Result:=Result + [exOverflow];
if em and _EM_UNDERFLOW <> 0 then
if em and _EM_UNDERFLOW = 0 then
Result:=Result + [exUnderflow];
if em and _EM_INEXACT <> 0 then
if em and _EM_INEXACT = 0 then
Result:=Result + [exPrecision];
end;
@ -156,18 +156,18 @@ var
c: dword;
begin
c:=0;
if exInvalidOp in Mask then
c:=c or _EM_INVALID;
if exDenormalized in Mask then
c:=c or _EM_DENORMAL;
if exZeroDivide in Mask then
c:=c or _EM_ZERODIVIDE;
if exOverflow in Mask then
c:=c or _EM_OVERFLOW;
if exUnderflow in Mask then
c:=c or _EM_UNDERFLOW;
if exPrecision in Mask then
c:=c or _EM_INEXACT;
if not(exInvalidOp in Mask) then
cw:=cw or _VFP_ENABLE_IM;
if not(exDenormalized in Mask) then
cw:=cw or _VFP_ENABLE_DM;
if not(exZeroDivide in Mask) then
cw:=cw or _VFP_ENABLE_ZM;
if not(exOverflow in Mask) then
cw:=cw or _VFP_ENABLE_OM;
if not(exUnderflow in Mask) then
cw:=cw or _VFP_ENABLE_UM;
if not(exPrecision in Mask) then
cw:=cw or _VFP_ENABLE_PM;
c:=_controlfp(c, _MCW_EM);
Result:=ConvertExceptionMask(c);
softfloat_exception_mask:=FPUExceptionMaskToSoftFloatMask(mask);
@ -281,22 +281,22 @@ function GetExceptionMask: TFPUExceptionMask;
Result:=[];
cw:=VFP_GetCW;
if (cw and _VFP_ENABLE_IM)<>0 then
if (cw and _VFP_ENABLE_IM)=0 then
include(Result,exInvalidOp);
if (cw and _VFP_ENABLE_DM)<>0 then
if (cw and _VFP_ENABLE_DM)=0 then
include(Result,exDenormalized);
if (cw and _VFP_ENABLE_ZM)<>0 then
if (cw and _VFP_ENABLE_ZM)=0 then
include(Result,exZeroDivide);
if (cw and _VFP_ENABLE_OM)<>0 then
if (cw and _VFP_ENABLE_OM)=0 then
include(Result,exOverflow);
if (cw and _VFP_ENABLE_UM)<>0 then
if (cw and _VFP_ENABLE_UM)=0 then
include(Result,exUnderflow);
if (cw and _VFP_ENABLE_PM)<>0 then
if (cw and _VFP_ENABLE_PM)=0 then
include(Result,exPrecision);
end;
@ -308,22 +308,22 @@ function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
cw:=VFP_GetCW and not(_VFP_ENABLE_ALL);
{$ifndef darwin}
if exInvalidOp in Mask then
if not(exInvalidOp in Mask) then
cw:=cw or _VFP_ENABLE_IM;
if exDenormalized in Mask then
if not(exDenormalized in Mask) then
cw:=cw or _VFP_ENABLE_DM;
if exZeroDivide in Mask then
if not(exZeroDivide in Mask) then
cw:=cw or _VFP_ENABLE_ZM;
if exOverflow in Mask then
if not(exOverflow in Mask) then
cw:=cw or _VFP_ENABLE_OM;
if exUnderflow in Mask then
if not(exUnderflow in Mask) then
cw:=cw or _VFP_ENABLE_UM;
if exPrecision in Mask then
if not(exPrecision in Mask) then
cw:=cw or _VFP_ENABLE_PM;
{$endif}
VFP_SetCW(cw);