Pārlūkot izejas kodu

--- Recording mergeinfo for merge of r39871 into '.':
U .
--- Recording mergeinfo for merge of r42891 into '.':
U .
--- Merging r43167 into '.':
U compiler/aarch64/cgcpu.pas
U rtl/aarch64/aarch64.inc
--- Recording mergeinfo for merge of r43167 into '.':
U .
--- Recording mergeinfo for merge of r45788 into '.':
G .
--- Merging r46870 into '.':
U rtl/linux/aarch64/sighnd.inc
U rtl/linux/aarch64/sighndh.inc
--- Recording mergeinfo for merge of r46870 into '.':
G .
--- Merging r46872 into '.':
G rtl/linux/aarch64/sighnd.inc
--- Recording mergeinfo for merge of r46872 into '.':
G .
--- Merging r46913 into '.':
U compiler/systems/t_linux.pas
--- Recording mergeinfo for merge of r46913 into '.':
G .

git-svn-id: branches/fixes_3_2@47037 -

florian 4 gadi atpakaļ
vecāks
revīzija
d0f65b36ab

+ 2 - 1
compiler/aarch64/cgcpu.pas

@@ -1044,6 +1044,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
@@ -1051,9 +1052,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;
 
 

+ 1 - 0
compiler/systems/t_linux.pas

@@ -164,6 +164,7 @@ begin
       LibrarySearchPath.AddLibraryPath(sysrootpath,'=/usr/lib/i386-linux-gnu',true);
 {$endif i386}
 {$ifdef aarch64}
+      LibrarySearchPath.AddLibraryPath(sysrootpath,'=/usr/lib64',true);
       LibrarySearchPath.AddLibraryPath(sysrootpath,'=/usr/lib/aarch64-linux-gnu',true);
 {$endif aarch64}
 {$ifdef powerpc}

+ 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;
 
 

+ 20 - 3
rtl/linux/aarch64/sighnd.inc

@@ -15,6 +15,8 @@
 
  **********************************************************************}
 
+{ $define SYSTEM_DEBUG}
+
 procedure SignalToRunerror(Sig: longint; SigInfo: PSigInfo; UContext: PUContext); public name '_FPC_DEFAULTSIGHANDLER'; cdecl;
 
 var
@@ -23,7 +25,19 @@ begin
   res:=0;
   case sig of
     SIGFPE:
+      begin
         res:=207;
+{$ifdef SYSTEM_DEBUG}
+        writeln('magic of FPSIMD_Context: $',hexstr(uContext^.uc_mcontext.FPSIMD_Context.head.magic,8));
+        writeln('size of FPSIMD_Context: $',hexstr(uContext^.uc_mcontext.FPSIMD_Context.head.size,8));
+{$endif SYSTEM_DEBUG}
+        if (uContext^.uc_mcontext.FPSIMD_Context.head.magic=$46508001) and
+           (uContext^.uc_mcontext.FPSIMD_Context.head.size=$210) then
+           begin
+             with uContext^.uc_mcontext.FPSIMD_Context do
+               fpsr:=fpsr and not(fpu_exception_mask shr fpu_exception_mask_to_status_mask_shift);
+           end;
+      end;
     SIGILL:
         res:=216;
     SIGSEGV :
@@ -38,7 +52,10 @@ begin
   reenable_signal(sig);
   { give runtime error at the position where the signal was raised }
   if res<>0 then
-    HandleErrorAddrFrame(res,
-      pointer(uContext^.uc_mcontext.pc),
-      pointer(uContext^.uc_mcontext.regs[29]));
+    begin
+      uContext^.uc_mcontext.regs[0]:=res;
+      uContext^.uc_mcontext.regs[1]:=uContext^.uc_mcontext.pc;
+      uContext^.uc_mcontext.regs[2]:=uContext^.uc_mcontext.regs[29];
+      pointer(uContext^.uc_mcontext.pc):=@HandleErrorAddrFrame;
+    end;
 end;

+ 16 - 2
rtl/linux/aarch64/sighndh.inc

@@ -17,6 +17,18 @@
 {$packrecords C}
 
 type
+  TAarch64_ctx = record
+    magic,
+    size : DWord
+  end;
+
+  TFPSIMD_Context = record
+    head : TAarch64_ctx;
+    fpsr,
+    fpcr : DWord;
+    vregs : array[0..31] of array[0..7] of Byte;
+  end;
+
   PSigContext = ^TSigContext;
   TSigContext = record
     fault_address : cULong;
@@ -25,10 +37,12 @@ type
     pc : cULong;
     pstate : cULong;
     __pad : cULong;
-    { The following field should be 16-byte-aligned. Currently the
+    { The following fields should be 16-byte-aligned. Currently the
       directive for specifying alignment is buggy, so the preceding
       field was added so that the record has the right size. }
-    __reserved : array[0..4095] of cUChar;
+    case Byte of
+      1: (__reserved : array[0..4095] of cUChar);
+      2: (FPSIMD_Context : TFPSIMD_Context);
   end;
 
   stack_t = record