Commit 1a2b99bc authored by FPK's avatar FPK
Browse files

* correctly reset fpu on x86_64-linux after a floating point exception,...

  * correctly reset fpu on x86_64-linux after a floating point exception, resolves second part of #37468

git-svn-id: trunk@46992 -
parent 202976b4
......@@ -18461,6 +18461,7 @@ tests/webtbs/tw37428.pp svneol=native#text/pascal
tests/webtbs/tw37449.pp svneol=native#text/pascal
tests/webtbs/tw37465.pp svneol=native#text/plain
tests/webtbs/tw37468.pp svneol=native#text/pascal
tests/webtbs/tw37468b.pp svneol=native#text/pascal
tests/webtbs/tw37477.pp svneol=native#text/pascal
tests/webtbs/tw37493.pp svneol=native#text/pascal
tests/webtbs/tw37508.pp svneol=native#text/pascal
......@@ -15,6 +15,7 @@
**********************************************************************}
{ $define SYSTEM_DEBUG}
{ use a trampoline which pushes the return address for proper unwinding }
Procedure SignalToHandleErrorAddrFrame (Errno : longint;addr : CodePointer; frame : Pointer); nostackframe; assembler;
......@@ -33,9 +34,8 @@ function GetFPUState(const SigContext : TSigContext) : word;
else
GetFPUState:=0;
{$ifdef SYSTEM_DEBUG}
writeln('xx:',sigcontext.twd,' ',sigcontext.cwd);
{$endif SYSTEM_DEBUG}
{$ifdef SYSTEM_DEBUG}
if assigned(SigContext.fpstate) then
writeln('Tag: ',sigcontext.fpstate^.twd,' Cw: ',sigcontext.fpstate^.cwd);
Writeln(stderr,'FpuState = ',result);
{$endif SYSTEM_DEBUG}
end;
......@@ -85,32 +85,45 @@ procedure SignalToRunerror(sig : longint; SigInfo: PSigInfo; SigContext: PSigCon
{ exceptions are handled, clear all flags
as we return from SignalToRunerrer, we have to clear the exception flags in the context }
if assigned(SigContext^.fpstate) then
SigContext^.fpstate^.swd:=SigContext^.fpstate^.swd and not(FPU_All);
SigContext^.fpstate^.swd:=SigContext^.fpstate^.swd and not($37ff);
end;
MMState:=getMMState(SigContext^);
if (MMState and MM_ExceptionMask)<>0 then
begin
{ first check the more precise options }
if (MMState and MM_DivisionByZero)<>0 then
res:=208
else if (MMState and MM_Invalid)<>0 Then
res:=207
else if (MMState and MM_Overflow)<>0 then
res:=205
else if (MMState and MM_Underflow)<>0 then
res:=206
else if (MMState and MM_Denormal)<>0 then
res:=216
else
res:=207; {'Coprocessor Error'}
MMState:=getMMState(SigContext^);
if (MMState and MM_ExceptionMask)<>0 then
begin
{ first check the more precise options }
if (MMState and MM_DivisionByZero)<>0 then
res:=208
else if (MMState and MM_Invalid)<>0 Then
res:=207
else if (MMState and MM_Overflow)<>0 then
res:=205
else if (MMState and MM_Underflow)<>0 then
res:=206
else if (MMState and MM_Denormal)<>0 then
res:=216
else
res:=207; {'Coprocessor Error'}
{ exceptions are handled, clear all flags
as we return from SignalToRunerrer, we have to clear the exception flags in the context }
if assigned(SigContext^.fpstate) then
SigContext^.fpstate^.mxcsr:=SigContext^.fpstate^.mxcsr and not(MM_ExceptionMask);
{ exceptions are handled, clear all flags
as we return from SignalToRunerrer, we have to clear the exception flags in the context }
if assigned(SigContext^.fpstate) then
SigContext^.fpstate^.mxcsr:=SigContext^.fpstate^.mxcsr and not(MM_ExceptionMask);
end;
if assigned(SigContext^.fpstate) then
with SigContext^.fpstate^ do
begin
{$ifdef SYSTEM_DEBUG}
Writeln(stderr,'fpstate^.swd = ',swd);
{$endif SYSTEM_DEBUG}
{ acutally, I am not sure if we should really touch the controll word }
cwd:=Default8087CW;
{ found by trial and error that setting to 0 means empty }
twd:=$0;
{ clear top }
swd:=swd and not($3700);
end;
SysResetFPU;
end;
SysResetFPU;
end;
SIGILL,
SIGBUS,
......
program Project1;
{$mode objfpc}{$H+}
uses math, sysutils
{ you can add units after this };
begin
try
writeln(power(0, -4));
except
on e: Exception do ClearExceptions(false);
end;
try
writeln(power(0, -3));
except
on e: Exception do ClearExceptions(false);
end;
try
writeln(power(0, -4));
except
on e: Exception do ClearExceptions(false);
end;
writeln('caught');
writeln(power(16, 0.5));
writeln('done');
end.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment