فهرست منبع

* ARM: SetExceptionMask and SetRoundingMode must return the old value of mask/mode respectively, not the new one.

git-svn-id: trunk@27217 -
sergei 11 سال پیش
والد
کامیت
67a8c315d8
1فایلهای تغییر یافته به همراه58 افزوده شده و 55 حذف شده
  1. 58 55
      rtl/arm/mathu.inc

+ 58 - 55
rtl/arm/mathu.inc

@@ -171,11 +171,9 @@ procedure VFP_SetCW(cw : dword); nostackframe; assembler;
   end;
 
 
-function GetRoundMode: TFPURoundingMode; 
-  var
-    rm: byte;
+function VFPCw2RoundingMode(cw: dword): TFPURoundingMode;
   begin
-    case (VFP_GetCW and _VFP_ROUNDINGMODE_MASK) shr _VFP_ROUNDINGMODE_MASK_SHIFT of
+    case (cw and _VFP_ROUNDINGMODE_MASK) shr _VFP_ROUNDINGMODE_MASK_SHIFT of
       0 : result := rmNearest;
       1 : result := rmUp;
       2 : result := rmDown;
@@ -184,32 +182,28 @@ function GetRoundMode: TFPURoundingMode;
   end;
 
 
+function GetRoundMode: TFPURoundingMode; 
+  begin
+    result:=VFPCw2RoundingMode(VFP_GetCW);
+  end;
+
+
 function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
   var
     mode: dword;
+    oldcw: dword;
   begin
     softfloat_rounding_mode:=RoundMode;
+    oldcw:=VFP_GetCW;
     case (RoundMode) of
-      rmNearest :
-        begin
-          mode := 0;
-        end;
-      rmUp :
-        begin
-          mode := 1;
-        end;
-      rmDown :
-        begin
-          mode := 2;
-        end;
-      rmTruncate :
-        begin
-          mode := 3;
-        end;
+      rmNearest :      mode := 0;
+      rmUp :           mode := 1;
+      rmDown :         mode := 2;
+      rmTruncate :     mode := 3;
     end;
     mode:=mode shl _VFP_ROUNDINGMODE_MASK_SHIFT;
-    VFP_SetCW((VFP_GetCW and (not _VFP_ROUNDINGMODE_MASK)) or mode);
-    result := RoundMode;
+    VFP_SetCW((oldcw and (not _VFP_ROUNDINGMODE_MASK)) or mode);
+    result := VFPCw2RoundingMode(oldcw);
   end;
 
 
@@ -226,13 +220,9 @@ function SetPrecisionMode(const Precision: TFPUPrecisionMode): TFPUPrecisionMode
   end;
 
 
-function GetExceptionMask: TFPUExceptionMask;
-  var
-    cw : dword;
+function VFPCw2ExceptionMask(cw: dword): TFPUExceptionMask;
   begin
     Result:=[];
-    cw:=VFP_GetCW;
-
     if (cw and _VFP_ENABLE_IM)=0 then
       include(Result,exInvalidOp);
 
@@ -253,11 +243,19 @@ function GetExceptionMask: TFPUExceptionMask;
   end;
 
 
+function GetExceptionMask: TFPUExceptionMask;
+  begin
+    Result:=VFPCw2ExceptionMask(VFP_GetCW);
+  end;
+
+
 function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
   var
     cw : dword;
   begin
-    cw:=VFP_GetCW and not(_VFP_ENABLE_ALL);
+    cw:=VFP_GetCW;
+    Result:=VFPCw2ExceptionMask(cw);
+    cw:=cw and not(_VFP_ENABLE_ALL);
 
 {$ifndef darwin}
     if not(exInvalidOp in Mask) then
@@ -279,8 +277,6 @@ function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
       cw:=cw or _VFP_ENABLE_PM;
 {$endif}
     VFP_SetCW(cw);
-    result:=Mask;
-
     softfloat_exception_mask:=Mask;
   end;
 
@@ -390,6 +386,30 @@ procedure FPU_SetCW(cw : dword); nostackframe; assembler;
   asm
     wfs r0
   end;
+
+
+function FPUCw2ExceptionMask(cw: dword): TFPUExceptionMask;
+  begin
+    Result:=[];
+
+    if (cw and _FPU_MASK_IM)=0 then
+      include(Result,exInvalidOp);
+
+    if (cw and _FPU_MASK_DM)=0 then
+      include(Result,exDenormalized);
+
+    if (cw and _FPU_MASK_ZM)=0 then
+      include(Result,exZeroDivide);
+
+    if (cw and _FPU_MASK_OM)=0 then
+      include(Result,exOverflow);
+
+    if (cw and _FPU_MASK_UM)=0 then
+      include(Result,exUnderflow);
+
+    if (cw and _FPU_MASK_PM)=0 then
+      include(Result,exPrecision);
+  end;
 {$endif}
 
 
@@ -401,8 +421,8 @@ function GetRoundMode: TFPURoundingMode;
 
 function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
   begin
+    result:=softfloat_rounding_mode;
     softfloat_rounding_mode:=RoundMode;
-    SetRoundMode:=RoundMode;
   end;
 
 
@@ -420,30 +440,9 @@ function SetPrecisionMode(const Precision: TFPUPrecisionMode): TFPUPrecisionMode
 
 
 function GetExceptionMask: TFPUExceptionMask;
-  var
-    cw : dword;
   begin
 {$if not(defined(gba)) and not(defined(nds)) and not(defined(FPUSOFT)) and not(defined(FPULIBGCC))}
-    Result:=[];
-    cw:=FPU_GetCW;
-
-    if (cw and _FPU_MASK_IM)=0 then
-      include(Result,exInvalidOp);
-
-    if (cw and _FPU_MASK_DM)=0 then
-      include(Result,exDenormalized);
-
-    if (cw and _FPU_MASK_ZM)=0 then
-      include(Result,exZeroDivide);
-
-    if (cw and _FPU_MASK_OM)=0 then
-      include(Result,exOverflow);
-
-    if (cw and _FPU_MASK_UM)=0 then
-      include(Result,exUnderflow);
-
-    if (cw and _FPU_MASK_PM)=0 then
-      include(Result,exPrecision);
+    Result:=FPUCw2ExceptionMask(FPU_GetCW);
 {$else}
     Result:=softfloat_exception_mask;
 {$endif}
@@ -455,7 +454,9 @@ function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
     cw : dword;
   begin
 {$if not(defined(gba)) and not(defined(nds)) and not(defined(FPUSOFT)) and not(defined(FPULIBGCC))}
-    cw:=FPU_GetCW or _FPU_MASK_ALL;
+    cw:=FPU_GetCW;
+    Result:=FPUCw2ExceptionMask(cw);
+    cw:=cw or _FPU_MASK_ALL;
 
     if exInvalidOp in Mask then
       cw:=cw and not(_FPU_MASK_IM);
@@ -476,14 +477,16 @@ function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
       cw:=cw and not(_FPU_MASK_PM);
 
     FPU_SetCW(cw);
+{$else}
+    Result:=softfloat_exception_mask;
 {$endif}
     softfloat_exception_mask:=Mask;
-    Result:=Mask;
   end;
 
 
 procedure ClearExceptions(RaisePending: Boolean =true);
   begin
+    softfloat_exception_flags:=[];
   end;
 
 {$endif wince}