Browse Source

o AArch64:
* properly initialize FPU
* FMOV cannot throw an FPU exception

git-svn-id: trunk@43167 -

florian 5 years ago
parent
commit
688c7d439f
2 changed files with 19 additions and 5 deletions
  1. 2 1
      compiler/aarch64/cgcpu.pas
  2. 17 4
      rtl/aarch64/aarch64.inc

+ 2 - 1
compiler/aarch64/cgcpu.pas

@@ -1024,6 +1024,7 @@ implementation
             { Notify the register allocator that we have written a move
               instruction so it can try to eliminate it. }
             add_move_instruction(instr);
+            { FMOV cannot generate a floating point exception }
           end
         else
           begin
@@ -1031,9 +1032,9 @@ implementation
                (reg_cgsize(reg2)<>tosize) then
               internalerror(2014110913);
             instr:=taicpu.op_reg_reg(A_FCVT,reg2,reg1);
+            maybe_check_for_fpu_exception(list);
           end;
         list.Concat(instr);
-        maybe_check_for_fpu_exception(list);
       end;
 
 

+ 17 - 4
rtl/aarch64/aarch64.inc

@@ -121,21 +121,34 @@ procedure fpc_throwfpuexception;[public,alias:'FPC_THROWFPUEXCEPTION'];
   end;
 
 
-procedure fpc_enable_fpu_exceptions;
+{$define FPC_SYSTEM_HAS_SYSINITFPU}
+procedure SysInitFPU;
   begin
+    softfloat_rounding_mode:=rmNearest;
+    { 0 is rmNearest }
+    setfpcr(getfpcr and $ff3fffff);
     { clear all "exception happened" flags we care about}
     setfpsr(getfpsr and not(fpu_exception_mask shr fpu_exception_mask_to_status_mask_shift));
     { enable invalid operations and division by zero exceptions. }
-    setfpcr((getfpcr and not(fpu_exception_mask)));
-    softfloat_exception_mask:=[exPrecision,exUnderflow,exInvalidOp];
+    setfpcr(((getfpcr and not(fpu_exception_mask)) or fpu_dze or fpu_ofe or fpu_ioe));
+    softfloat_exception_mask:=[float_flag_underflow,float_flag_inexact,float_flag_denormal];
+    softfloat_exception_flags:=[];
   end;
 
 
+{$define FPC_SYSTEM_HAS_SYSRESETFPU}
+Procedure SysResetFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
+begin
+  softfloat_exception_flags:=[];
+  setfpsr(getfpsr and not(FPSR_EXCEPTIONS));
+end;
+
+
 procedure fpc_cpuinit;
   begin
     { don't let libraries influence the FPU cw set by the host program }
     if not IsLibrary then
-      fpc_enable_fpu_exceptions;
+      SysInitFPU;
   end;