mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 13:08:49 +02:00
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:
parent
90d2982977
commit
3b39ec84e4
@ -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'}
|
||||
|
Loading…
Reference in New Issue
Block a user