Переглянути джерело

* check first for x86 exception and only for sse if no x87 exceptions is thrown, clear all exception afterwards
* throw rte 206 instead of rte 216 for denormal on m68k-linux as well

git-svn-id: trunk@47117 -

florian 5 роки тому
батько
коміт
91fe098eb4
3 змінених файлів з 46 додано та 46 видалено
  1. 21 18
      rtl/linux/i386/sighnd.inc
  2. 1 1
      rtl/linux/m68k/sighnd.inc
  3. 24 27
      rtl/linux/x86_64/sighnd.inc

+ 21 - 18
rtl/linux/i386/sighnd.inc

@@ -63,26 +63,29 @@ begin
                       res:=206
                     else
                       res:=207;  {'Coprocessor Error'}
-                  end;
-                { SSE data? }
-                if ucontext^.uc_mcontext.fpstate^.magic=0 then
+                  end
+                else
                   begin
-                    MMState:=ucontext^.uc_mcontext.fpstate^.mxcsr;
-                    if (MMState and MM_ExceptionMask)<>0 then
+                    { SSE data? }
+                    if ucontext^.uc_mcontext.fpstate^.magic=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:=206
-                        else
-                          res:=207;  {'Coprocessor Error'}
+                        MMState:=ucontext^.uc_mcontext.fpstate^.mxcsr;
+                        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:=206
+                            else
+                              res:=207;  {'Coprocessor Error'}
+                          end;
                       end;
                   end;
                end;

+ 1 - 1
rtl/linux/m68k/sighnd.inc

@@ -111,7 +111,7 @@ begin
               else if (FpuState and (Underflow or AE_Underflow))<>0 then
                 res:=206
               else if (FpuState and PSR_Denormal)<>0 then
-                res:=216
+                res:=206
               { 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

+ 24 - 27
rtl/linux/x86_64/sighnd.inc

@@ -81,33 +81,26 @@ procedure SignalToRunerror(sig : longint; SigInfo: PSigInfo; SigContext: PSigCon
                     res:=207
                   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^.swd:=SigContext^.fpstate^.swd and not($37ff);
-                end;
-              MMState:=getMMState(SigContext^);
-              if (MMState and MM_ExceptionMask)<>0 then
+                end
+              else
                 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:=206
-                  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);
+                  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:=206
+                      else
+                        res:=207;  {'Coprocessor Error'}
+                    end;
                 end;
               if assigned(SigContext^.fpstate) then
                 with SigContext^.fpstate^ do
@@ -115,12 +108,16 @@ procedure SignalToRunerror(sig : longint; SigInfo: PSigInfo; SigContext: PSigCon
   {$ifdef SYSTEM_DEBUG}
                     Writeln(stderr,'fpstate^.swd = ',swd);
   {$endif SYSTEM_DEBUG}
-                    { acutally, I am not sure if we should really touch the controll word }
+                    { actually, 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);
+                    { exceptions are handled, clear all flags
+                      as we return from SignalToRunerrer, we have to clear the exception flags in the context }
+                    mxcsr:=mxcsr and not(MM_ExceptionMask);
+                    swd:=swd and not($37ff);
                   end;
             end;
         end;