Browse Source

MIPS RTL:
+ fixed missing result assignments in SetRoundMode and SetExceptionMask.
* GetRoundMode: provide correct mapping from FSR bits to TRoundingMode.
* SetExceptionMask: simplified.

git-svn-id: trunk@25079 -

sergei 12 years ago
parent
commit
0cea8466a2
1 changed files with 37 additions and 49 deletions
  1. 37 49
      rtl/mips/mathu.inc

+ 37 - 49
rtl/mips/mathu.inc

@@ -54,39 +54,34 @@ begin
       result:=result or (1 shl ord(exPrecision));
 end;
 
+const
+  roundmode2fsr : array [TFPURoundingMode] of byte=(
+    fpu_rounding_nearest,
+    fpu_rounding_minus_inf,
+    fpu_rounding_plus_inf,
+    fpu_rounding_towards_zero
+  );
+
+  fsr2roundmode : array [0..3] of TFPURoundingMode = (
+    rmNearest,
+    rmTruncate,
+    rmUp,
+    rmDown
+  );
+
 function GetRoundMode: TFPURoundingMode;
   begin
-    result:=TFPURoundingMode(get_fsr and 3);
+    result:=fsr2roundmode[get_fsr and fpu_rounding_mask];
   end;
 
 function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
   var
-    fpu_round : longint;
+    fsr: longword;
   begin
-    case (RoundMode) of
-      rmNearest :
-        begin
-          softfloat_rounding_mode := float_round_nearest_even;
-          fpu_round:=fpu_rounding_nearest;
-        end;
-      rmTruncate :
-        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);
+    softfloat_rounding_mode:=byte(RoundMode);
+    fsr:=get_fsr;
+    result:=fsr2roundmode[fsr and fpu_rounding_mask];
+    set_fsr((fsr and not fpu_rounding_mask) or roundmode2fsr[RoundMode]);
   end;
 
 
@@ -102,11 +97,8 @@ function SetPrecisionMode(const Precision: TFPUPrecisionMode): TFPUPrecisionMode
   end;
 
 
-function GetExceptionMask: TFPUExceptionMask;
-  var
-    fsr : dword;
+function fsr2ExceptionMask(fsr: longword): TFPUExceptionMask;
   begin
-    fsr:=get_fsr;
     result:=[];
     { invalid operation }
     if (fsr and fpu_enable_invalid)=0 then
@@ -130,46 +122,42 @@ function GetExceptionMask: TFPUExceptionMask;
   end;
 
 
+function GetExceptionMask: TFPUExceptionMask;
+  begin
+    result:=fpu2ExceptionMask(get_fsr);
+  end;
+
 
 function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
   var
-    fsr : dword;
+    fsr : longword;
   begin
     fsr:=get_fsr;
+    result:=fsr2ExceptionMask(fsr);
+
+    { Reset flags, cause and enables }
+    fsr := fsr and not (fpu_flags_mask or fpu_cause_mask or fpu_enable_mask);
 
     { invalid operation }
-    if (exInvalidOp in mask) then
-      fsr:=fsr and not(fpu_enable_invalid)
-    else
+    if not (exInvalidOp in mask) then
       fsr:=fsr or (fpu_enable_invalid);
 
     { zero divide }
-    if (exZeroDivide in mask) then
-      fsr:=fsr and not(fpu_enable_div_zero)
-    else
+    if not (exZeroDivide in mask) then
       fsr:=fsr or (fpu_enable_div_zero);
 
     { overflow }
-    if (exOverflow in mask) then
-      fsr:=fsr and not(fpu_enable_overflow)
-    else
+    if not (exOverflow in mask) then
       fsr:=fsr or (fpu_enable_overflow);
 
     { underflow }
-    if (exUnderflow in mask) then
-      fsr:=fsr and not(fpu_enable_underflow)
-    else
+    if not (exUnderflow in mask) then
       fsr:=fsr or (fpu_enable_underflow);
 
     { Precision (inexact result) }
-    if (exPrecision in mask) then
-      fsr:=fsr and not(fpu_enable_inexact)
-    else
+    if not (exPrecision in mask) then
       fsr:=fsr or (fpu_enable_inexact);
 
-    { Reset flags and cause }
-    fsr := fsr and not (fpu_flags_mask or fpu_cause_mask);
-
     { update control register contents }
     set_fsr(fsr);