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