Jelajahi Sumber

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

git-svn-id: trunk@43909 -
pierre 5 tahun lalu
induk
melakukan
3b39ec84e4
1 mengubah file dengan 50 tambahan dan 27 penghapusan
  1. 50 27
      rtl/linux/m68k/sighnd.inc

+ 50 - 27
rtl/linux/m68k/sighnd.inc

@@ -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'}