On 14/07/16 02:48, peter green wrote:
tags 830906 +patch
oops, patch attatched.

Further arm64 changes taken from the fixes_3_0_ios branch after add-arm64-patch

This seems to fix the startup crash of the textmode ide.

Generated with

svn diff http://svn.freepascal.org/svn/fpc/branches/fixes_3_0_ios@32015 http://svn.freepascal.org/svn/fpc/branches/fixes_3_0_ios@34101 > ../fpc-svnbranchdiff
cat ../fpc-svnbranchdiff | filterdiff -p0 '-icompiler/aarch64/*' --addoldprefix=a/fpcsrc/ --addnewprefix=b/fpcsrc/ | filterdiff -p1 -xfpcsrc/compiler/aarch64/symcpu.pas > debian/patches/further-arm64-fixes.patch

The changes in symcpu.pas were excluded because they 


--- a/fpcsrc/compiler/aarch64/cgcpu.pas	(revision 32015)
+++ b/fpcsrc/compiler/aarch64/cgcpu.pas	(revision 34101)
@@ -813,7 +813,7 @@
         if fromsize in [OS_64,OS_S64] then
           begin
             { split into two 32 bit loads }
-            hreg1:=makeregsize(register,OS_32);
+            hreg1:=getintregister(list,OS_32);
             hreg2:=getintregister(list,OS_32);
             if target_info.endian=endian_big then
               begin
@@ -832,6 +832,7 @@
                 inc(href.offset,4);
                 a_load_ref_reg(list,OS_32,OS_32,href,hreg2);
               end;
+            a_load_reg_reg(list,OS_32,OS_64,hreg1,register);
             list.concat(taicpu.op_reg_reg_const_const(A_BFI,register,makeregsize(hreg2,OS_64),32,32));
           end
        else
@@ -1116,8 +1117,9 @@
         if fromsize in [OS_64,OS_S64] then
           begin
             { split into two 32 bit stores }
-            hreg1:=makeregsize(register,OS_32);
+            hreg1:=getintregister(list,OS_32);
             hreg2:=getintregister(list,OS_32);
+            a_load_reg_reg(list,OS_32,OS_32,makeregsize(register,OS_32),hreg1);
             a_op_const_reg_reg(list,OP_SHR,OS_64,32,register,makeregsize(hreg2,OS_64));
             if target_info.endian=endian_big then
               begin
@@ -1341,7 +1343,7 @@
 
     procedure tcgaarch64.a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: topcg; size: tcgsize; src1, src2, dst: tregister; setflags : boolean; var ovloc : tlocation);
       var
-        tmpreg1: tregister;
+        tmpreg1, tmpreg2: tregister;
       begin
         ovloc.loc:=LOC_VOID;
         { overflow can only occur with 64 bit calculations on 64 bit cpus }
@@ -1361,9 +1363,7 @@
                       ovloc.resflags:=F_CC
                   else
                     ovloc.resflags:=F_VS;
-                  { finished; since we won't call through to a_op_reg_reg_reg,
-                    adjust the result here if necessary }
-                  maybeadjustresult(list,op,size,dst);
+                  { finished }
                   exit;
                 end;
               OP_MUL:
@@ -1378,17 +1378,22 @@
                 end;
               OP_IMUL:
                 begin
-                  { check whether the sign bit of the (128 bit) result is the
-                    same as "sign bit of src1" xor "signbit of src2" (if so, no
-                    overflow and the xor-product of all sign bits is 0) }
+                  { check whether the upper 64 bits of the 128 bit multiplication
+                    result have the same value as the replicated sign bit of the
+                    lower 64 bits }
                   tmpreg1:=getintregister(list,OS_64);
                   list.concat(taicpu.op_reg_reg_reg(A_SMULH,tmpreg1,src2,src1));
-                  list.concat(taicpu.op_reg_reg_reg(A_EOR,tmpreg1,tmpreg1,src1));
-                  list.concat(taicpu.op_reg_reg_reg(A_EOR,tmpreg1,tmpreg1,src2));
-                  list.concat(taicpu.op_reg_const(A_TST,tmpreg1,$80000000));
+                  { calculate lower 64 bits (afterwards, because dst may be
+                    equal to src1 or src2) }
+                  a_op_reg_reg_reg(list,op,size,src1,src2,dst);
+                  { replicate sign bit }
+                  tmpreg2:=getintregister(list,OS_64);
+                  a_op_const_reg_reg(list,OP_SAR,OS_S64,63,dst,tmpreg2);
+                  list.concat(taicpu.op_reg_reg(A_CMP,tmpreg1,tmpreg2));
                   ovloc.loc:=LOC_FLAGS;
                   ovloc.resflags:=F_NE;
-                  { still have to perform the actual multiplication }
+                  { finished }
+                  exit;
                 end;
               OP_IDIV,
               OP_DIV:
--- a/fpcsrc/compiler/aarch64/ncpucnv.pas	(revision 32015)
+++ b/fpcsrc/compiler/aarch64/ncpucnv.pas	(revision 34101)
@@ -163,6 +163,10 @@
        exit;
 
       case left.location.loc of
+        LOC_SUBSETREG,
+        LOC_CSUBSETREG,
+        LOC_SUBSETREF,
+        LOC_CSUBSETREF,
         LOC_CREFERENCE,
         LOC_REFERENCE,
         LOC_REGISTER,
--- a/fpcsrc/compiler/aarch64/hlcgcpu.pas	(revision 32015)
+++ b/fpcsrc/compiler/aarch64/hlcgcpu.pas	(revision 34101)
@@ -136,7 +136,8 @@
     begin
       if slopt in [SL_SETZERO,SL_SETMAX] then
         inherited
-      else if not(sreg.bitlen in [32,64]) then
+      else if not(sreg.bitlen in [32,64]) or
+              (sreg.startbit<>0) then
         begin
           makeregssamesize(list,def_cgsize(fromsize),sreg.subsetregsize,fromreg,sreg.subsetreg,fromreg,toreg);
           list.concat(taicpu.op_reg_reg_const_const(A_BFI,toreg,fromreg,sreg.startbit,sreg.bitlen))

Reply via email to