From: Pascal Packaging Team Date: Fri, 2 Mar 2018 08:13:21 +0000 (+0000) Subject: further-arm64-fixes X-Git-Tag: archive/raspbian/3.0.4+dfsg-17+rpi1^2^2~14 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=80a89cdaa185fd575800ed70ec95d962be5a4c4c;p=fpc.git further-arm64-fixes 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 Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=830906 Gbp-Pq: Name further-arm64-fixes.patch --- diff --git a/fpcsrc/compiler/aarch64/cgcpu.pas b/fpcsrc/compiler/aarch64/cgcpu.pas index 7faf7809..6e630153 100644 --- a/fpcsrc/compiler/aarch64/cgcpu.pas +++ b/fpcsrc/compiler/aarch64/cgcpu.pas @@ -813,7 +813,7 @@ implementation 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 @@ implementation 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 @@ implementation 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 @@ implementation 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 @@ implementation 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 @@ implementation 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: diff --git a/fpcsrc/compiler/aarch64/hlcgcpu.pas b/fpcsrc/compiler/aarch64/hlcgcpu.pas index bdcecce0..1238d451 100644 --- a/fpcsrc/compiler/aarch64/hlcgcpu.pas +++ b/fpcsrc/compiler/aarch64/hlcgcpu.pas @@ -136,7 +136,8 @@ implementation 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)) diff --git a/fpcsrc/compiler/aarch64/ncpucnv.pas b/fpcsrc/compiler/aarch64/ncpucnv.pas index 459d47a7..f9124a01 100644 --- a/fpcsrc/compiler/aarch64/ncpucnv.pas +++ b/fpcsrc/compiler/aarch64/ncpucnv.pas @@ -163,6 +163,10 @@ implementation exit; case left.location.loc of + LOC_SUBSETREG, + LOC_CSUBSETREG, + LOC_SUBSETREF, + LOC_CSUBSETREF, LOC_CREFERENCE, LOC_REFERENCE, LOC_REGISTER,