* cause bits must be clear as flags to avoid a second FPU exception

git-svn-id: trunk@21844 -
This commit is contained in:
pierre 2012-07-10 12:31:46 +00:00
parent bc1ecc2e94
commit c234eae68a
2 changed files with 10 additions and 3 deletions

View File

@ -27,6 +27,8 @@ const
default_fpu_enable = fpu_enable_div_zero or fpu_enable_invalid; default_fpu_enable = fpu_enable_div_zero or fpu_enable_invalid;
fpu_flags_mask = $7C; fpu_flags_mask = $7C;
fpu_cause_mask = $3F000;
{ FPU rounding mask and values } { FPU rounding mask and values }
fpu_rounding_mask = $3; fpu_rounding_mask = $3;
fpu_rounding_nearest = 0; fpu_rounding_nearest = 0;
@ -166,6 +168,9 @@ function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
else else
fsr:=fsr or (fpu_enable_inexact); fsr:=fsr or (fpu_enable_inexact);
{ Reset flags and cause }
fsr := fsr and not (fpu_flags_mask or fpu_cause_mask);
{ update control register contents } { update control register contents }
set_fsr(fsr); set_fsr(fsr);
@ -175,6 +180,6 @@ function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
procedure ClearExceptions(RaisePending: Boolean =true); procedure ClearExceptions(RaisePending: Boolean =true);
begin begin
set_fsr(get_fsr and $fffffc1f); set_fsr(get_fsr and not (fpu_flags_mask or fpu_cause_mask));
end; end;

View File

@ -48,6 +48,8 @@ const
default_fpu_enable = fpu_enable_div_zero or fpu_enable_invalid; default_fpu_enable = fpu_enable_div_zero or fpu_enable_invalid;
fpu_flags_mask = $7C; fpu_flags_mask = $7C;
fpu_cause_mask = $3F000;
{ FPU rounding mask and values } { FPU rounding mask and values }
fpu_rounding_mask = $3; fpu_rounding_mask = $3;
fpu_rounding_nearest = 0; fpu_rounding_nearest = 0;
@ -67,8 +69,8 @@ var
{ enable div by 0 and invalid operation fpu exceptions, { enable div by 0 and invalid operation fpu exceptions,
disable the other exceptions } disable the other exceptions }
tmp32 := (tmp32 and not fpu_enable_mask) or default_fpu_enable; tmp32 := (tmp32 and not fpu_enable_mask) or default_fpu_enable;
{ Reset flags } { Reset flags and cause }
tmp32 := tmp32 and not fpu_flags_mask; tmp32 := tmp32 and not (fpu_flags_mask or fpu_cause_mask);
{ round towards nearest; ieee compliant arithmetics } { round towards nearest; ieee compliant arithmetics }
tmp32 := (tmp32 and not fpu_rounding_mask) or fpu_rounding_nearest; tmp32 := (tmp32 and not fpu_rounding_mask) or fpu_rounding_nearest;