Examine all exception bits in m68k fpsr register to decide which into which run time error it is converted

git-svn-id: trunk@43909 -
This commit is contained in:
pierre 2020-01-10 22:58:34 +00:00
parent 90d2982977
commit 3b39ec84e4

View File

@ -20,6 +20,7 @@ const
{ Bits in control register }
RoundingMode = $30;
RoundingPrecision = $c0;
{ Exception bits common to status and control registers }
InexactDecimal = $100;
InexactOperation = $200;
DivideByZero = $400;
@ -27,38 +28,60 @@ const
OverFlow = $1000;
OperandError = $2000;
SignalingNaN = $4000;
BranchOnUnordered = $800;
BranchOnUnordered = $8000;
FPU_ES_Mask = $ff00;
{ Accrued exception bit only in status register }
AE_Inexact = $8;
AE_DivideByZero = $10;
AE_Underflow = $20;
AE_Overflow = $40;
AE_InvalidOperation = $80;
FPU_AE_Mask = $F80;
fpucw : longint = {InexactOperation or }DivideByZero or
reset_fpucw : longint = {InexactOperation or }DivideByZero or
OverFlow or OperandError or
SignalingNaN or BranchOnUnordered;
fpust : longint = 0;
{ Bits in status register }
FPU_Invalid = $80;
FPU_Denormal = $8;
FPU_DivisionByZero = $10;
FPU_Overflow = $40;
FPU_Underflow = $20;
{ m68k is not stack based }
FPU_StackUnderflow = $0;
FPU_StackOverflow = $0;
FPU_All = $f8;
reset_fpust : longint = 0;
{ Bits in psr SigContext field }
PSR_Invalid = $80;
PSR_Denormal = $8;
PSR_DivisionByZero = $10;
PSR_Overflow = $40;
PSR_Underflow = $20;
{ m68k is not stack based }
PSR_StackUnderflow = $0;
PSR_StackOverflow = $0;
FPU_Status_Exception_Mask = FPU_ES_Mask or FPU_AE_Mask;
PSR_Exception_Mask =$f8;
FPU_Control_Exception_Mask = FPU_ES_Mask;
Procedure ResetFPU;
var
l_fpucw : longint;
begin
{$ifdef CPU68020}
asm
fmove.l fpcr,l_fpucw
end;
{ Reset only exception based control bits in fpcr }
l_fpucw := (l_fpucw and not (dword(FPU_Control_Exception_Mask)))
or (reset_fpucw and FPU_Control_Exception_Mask);
asm
fmove.l fpucw,fpcr
fmove.l fpust,fpsr
fmove.l l_fpucw,fpcr
{ Reset fpsr to zero }
fmove.l reset_fpust,fpsr
end;
{$endif}
end;
function GetFPUState(const SigContext : TSigContext) : longint;
function GetFPUState(const SigContext : TSigContext) : dword;
begin
GetfpuState:=SigContext.psr;
GetfpuState:=dword(SigContext.psr);
{$ifdef SYSTEM_DEBUG}
Writeln(stderr,'FpuState = ',GetFpuState);
{$endif SYSTEM_DEBUG}
@ -68,7 +91,8 @@ end;
procedure SignalToRunerror(Sig: longint; Info : pointer; var SigContext: TSigContext); public name '_FPC_DEFAULTSIGHANDLER'; cdecl;
var
res,fpustate : word;
res : word;
fpustate : dword;
begin
res:=0;
case sig of
@ -78,21 +102,20 @@ begin
how to tell if it is or not PM }
res:=200;
fpustate:=GetFPUState(SigContext);
if (FpuState and FPU_All) <> 0 then
if (FpuState and FPU_Status_Exception_Mask) <> 0 then
begin
{ first check the more precise options }
if (FpuState and FPU_DivisionByZero)<>0 then
if (FpuState and (DivideByZero or AE_DividebyZero))<>0 then
res:=200
else if (FpuState and FPU_Overflow)<>0 then
else if (FpuState and (Overflow or AE_Overflow))<>0 then
res:=205
else if (FpuState and FPU_Underflow)<>0 then
else if (FpuState and (Underflow or AE_Underflow))<>0 then
res:=206
else if (FpuState and FPU_Denormal)<>0 then
else if (FpuState and PSR_Denormal)<>0 then
res:=216
else if (FpuState and (FPU_StackOverflow or FPU_StackUnderflow))<>0 then
res:=207
else if (FpuState and FPU_Invalid)<>0 then
{ else if (FpuState and (PSR_StackOverflow or PRS_StackUnderflow))<>0 then
res:=207, disabled, as there is no fpu stack }
else if (FpuState and (OperandError or SignalingNan or BranchOnUnordered or AE_InvalidOperation))<>0 then
res:=216
else
res:=207; {'Coprocessor Error'}