Bläddra i källkod

--- 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 år sedan
förälder
incheckning
d0f65b36ab

+ 2 - 1
compiler/aarch64/cgcpu.pas

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

+ 1 - 0
compiler/systems/t_linux.pas

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

+ 17 - 4
rtl/aarch64/aarch64.inc

@@ -121,21 +121,34 @@ procedure fpc_throwfpuexception;[public,alias:'FPC_THROWFPUEXCEPTION'];
   end;
   end;
 
 
 
 
-procedure fpc_enable_fpu_exceptions;
+{$define FPC_SYSTEM_HAS_SYSINITFPU}
+procedure SysInitFPU;
   begin
   begin
+    softfloat_rounding_mode:=rmNearest;
+    { 0 is rmNearest }
+    setfpcr(getfpcr and $ff3fffff);
     { clear all "exception happened" flags we care about}
     { clear all "exception happened" flags we care about}
     setfpsr(getfpsr and not(fpu_exception_mask shr fpu_exception_mask_to_status_mask_shift));
     setfpsr(getfpsr and not(fpu_exception_mask shr fpu_exception_mask_to_status_mask_shift));
     { enable invalid operations and division by zero exceptions. }
     { 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;
   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;
 procedure fpc_cpuinit;
   begin
   begin
     { don't let libraries influence the FPU cw set by the host program }
     { don't let libraries influence the FPU cw set by the host program }
     if not IsLibrary then
     if not IsLibrary then
-      fpc_enable_fpu_exceptions;
+      SysInitFPU;
   end;
   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;
 procedure SignalToRunerror(Sig: longint; SigInfo: PSigInfo; UContext: PUContext); public name '_FPC_DEFAULTSIGHANDLER'; cdecl;
 
 
 var
 var
@@ -23,7 +25,19 @@ begin
   res:=0;
   res:=0;
   case sig of
   case sig of
     SIGFPE:
     SIGFPE:
+      begin
         res:=207;
         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:
     SIGILL:
         res:=216;
         res:=216;
     SIGSEGV :
     SIGSEGV :
@@ -38,7 +52,10 @@ begin
   reenable_signal(sig);
   reenable_signal(sig);
   { give runtime error at the position where the signal was raised }
   { give runtime error at the position where the signal was raised }
   if res<>0 then
   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;
 end;

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

@@ -17,6 +17,18 @@
 {$packrecords C}
 {$packrecords C}
 
 
 type
 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;
   PSigContext = ^TSigContext;
   TSigContext = record
   TSigContext = record
     fault_address : cULong;
     fault_address : cULong;
@@ -25,10 +37,12 @@ type
     pc : cULong;
     pc : cULong;
     pstate : cULong;
     pstate : cULong;
     __pad : 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
       directive for specifying alignment is buggy, so the preceding
       field was added so that the record has the right size. }
       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;
   end;
 
 
   stack_t = record
   stack_t = record