Explorar o código

Really use get_fsr set_fsr functions

git-svn-id: trunk@21721 -
pierre %!s(int64=13) %!d(string=hai) anos
pai
achega
ef3bbf4c4a
Modificáronse 1 ficheiros con 76 adicións e 42 borrados
  1. 76 42
      rtl/mips/mathu.inc

+ 76 - 42
rtl/mips/mathu.inc

@@ -13,8 +13,27 @@
  **********************************************************************}
 
 { exported by the system unit }
-//!!!function get_fsr : dword;external name 'FPC_GETFSR';
-//!!!procedure set_fsr(fsr : dword);external name 'FPC_SETFSR';
+function get_fsr : dword;external name 'FPC_GETFSR';
+procedure set_fsr(fsr : dword);external name 'FPC_SETFSR';
+
+const
+  { FPU enable exception bits for FCSR register }
+  fpu_enable_inexact   =  $80;
+  fpu_enable_underflow = $100;
+  fpu_enable_overflow  = $200;
+  fpu_enable_div_zero  = $400;
+  fpu_enable_invalid   = $800;
+  fpu_enable_mask      = $F80;
+  default_fpu_enable = fpu_enable_div_zero or fpu_enable_invalid;
+
+  fpu_flags_mask = $7C;
+  { FPU rounding mask and values }
+  fpu_rounding_mask    = $3;
+  fpu_rounding_nearest = 0;
+  fpu_rounding_towards_zero = 1;
+  fpu_rounding_plus_inf = 2;
+  fpu_rounding_minus_inf = 3;
+
 
 function FPUExceptionMaskToSoftFloatMask(const Mask: TFPUExceptionMask): byte;
 begin
@@ -35,22 +54,37 @@ end;
 
 function GetRoundMode: TFPURoundingMode;
   begin
-//!!!    result:=TFPURoundingMode(get_fsr shr 30);
+    result:=TFPURoundingMode(get_fsr and 3);
   end;
 
 function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
+  var
+    fpu_round : longint;
   begin
+    
     case (RoundMode) of
       rmNearest :
-        softfloat_rounding_mode := float_round_nearest_even;
+        begin
+		  softfloat_rounding_mode := float_round_nearest_even;
+		  fpu_round:=fpu_rounding_mearest;
+		end;
       rmTruncate :
-        softfloat_rounding_mode := float_round_to_zero;
-      rmUp :
-        softfloat_rounding_mode := float_round_up;
-      rmDown :
-        softfloat_rounding_mode := float_round_down;
-    end;
-//!!!    set_fsr((get_fsr and $3fffffff) or (dword(RoundMode) shl 30));
+        begin
+	      softfloat_rounding_mode := float_round_to_zero;
+   		  fpu_round:=fpu_rounding_towards_zero;
+		end;
+   rmUp :
+        begin
+	      softfloat_rounding_mode := float_round_up;
+   		  fpu_round:=fpu_rounding_plus_inf;
+		end;
+   rmDown :
+        begin
+	      softfloat_rounding_mode := float_round_down;
+   		  fpu_round:=fpu_rounding_minus_inf;
+		end;
+ end;
+    set_fsr((get_fsr and not fpu_rounding_mask) or fpu_round);
 //!!!    result:=TFPURoundingMode(get_fsr shr 30);
   end;
 
@@ -71,26 +105,26 @@ function GetExceptionMask: TFPUExceptionMask;
   var
     fsr : dword;
   begin
-//!!!    fsr:=get_fsr;
+    fsr:=get_fsr;
     result:=[];
-    { invalid operation: bit 27 }
-    if (fsr and (1 shl 27))=0 then
+    { invalid operation }
+    if (fsr and fpu_enable_invalid)=0 then
       include(result,exInvalidOp);
 
-    { zero divide: bit 24 }
-    if (fsr and (1 shl 24))=0 then
-      include(result,exInvalidOp);
+    { zero divide }
+    if (fsr and fpu_enable_div_zero)=0 then
+      include(result,exZeroDivide);
 
-    { overflow: bit 26 }
-    if (fsr and (1 shl 26))=0 then
-      include(result,exInvalidOp);
+    { overflow }
+    if (fsr and fpu_enable_overflow)=0 then
+      include(result,exOverflow);
 
-    { underflow: bit 25 }
-    if (fsr and (1 shl 25))=0 then
+    { underflow: }
+    if (fsr and fpu_enable_underflow)=0 then
       include(result,exUnderflow);
 
-    { Precision (inexact result): bit 23 }
-    if (fsr and (1 shl 23))=0 then
+    { Precision (inexact result) }
+    if (fsr and fpu_enable_inexact)=0 then
       include(result,exPrecision);
   end;
 
@@ -100,40 +134,40 @@ function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
   var
     fsr : dword;
   begin
-//!!!    fsr:=get_fsr;
+    fsr:=get_fsr;
 
-    { invalid operation: bit 27 }
+    { invalid operation }
     if (exInvalidOp in mask) then
-      fsr:=fsr and not(1 shl 27)
+      fsr:=fsr and not(fpu_enable_invalid)
     else
-      fsr:=fsr or (1 shl 27);
+      fsr:=fsr or (fpu_enable_invalid);
 
-    { zero divide: bit 24 }
+    { zero divide }
     if (exZeroDivide in mask) then
-      fsr:=fsr and not(1 shl 24)
+      fsr:=fsr and not(fpu_enable_div_zero)
     else
-      fsr:=fsr or (1 shl 24);
+      fsr:=fsr or (fpu_enable_div_zero);
 
-    { overflow: bit 26 }
+    { overflow }
     if (exOverflow in mask) then
-      fsr:=fsr and not(1 shl 26)
+      fsr:=fsr and not(fpu_enable_overflow)
     else
-      fsr:=fsr or (1 shl 26);
+      fsr:=fsr or (fpu_enable_overflow);
 
-    { underflow: bit 25 }
+    { underflow }
     if (exUnderflow in mask) then
-      fsr:=fsr and not(1 shl 25)
+      fsr:=fsr and not(fpu_enable_underflow)
     else
-      fsr:=fsr or (1 shl 25);
+      fsr:=fsr or (fpu_enable_underflow);
 
-    { Precision (inexact result): bit 23 }
+    { Precision (inexact result) }
     if (exPrecision in mask) then
-      fsr:=fsr and not(1 shl 23)
+      fsr:=fsr and not(fpu_enable_inexact)
     else
-      fsr:=fsr or (1 shl 23);
+      fsr:=fsr or (fpu_enable_inexact);
 
     { update control register contents }
-//!!!    set_fsr(fsr);
+    set_fsr(fsr);
 
     softfloat_exception_mask:=FPUExceptionMaskToSoftFloatMask(mask);
   end;
@@ -141,6 +175,6 @@ function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
 
 procedure ClearExceptions(RaisePending: Boolean =true);
   begin
-//!!!    set_fsr(get_fsr and $fffffc1f);
+    set_fsr(get_fsr and $fffffc1f);
   end;