浏览代码

* Aarch64: fix 32 bit div operations with constant denominators, resolves #38225

git-svn-id: trunk@47812 -
florian 4 年之前
父节点
当前提交
072be7b0f7
共有 3 个文件被更改,包括 48 次插入8 次删除
  1. 1 0
      .gitattributes
  2. 10 8
      compiler/aarch64/ncpumat.pas
  3. 37 0
      tests/webtbs/tw38225.pp

+ 1 - 0
.gitattributes

@@ -18612,6 +18612,7 @@ tests/webtbs/tw38151.pp svneol=native#text/pascal
 tests/webtbs/tw38164.pp svneol=native#text/pascal
 tests/webtbs/tw38201.pp svneol=native#text/pascal
 tests/webtbs/tw38202.pp svneol=native#text/pascal
+tests/webtbs/tw38225.pp svneol=native#text/pascal
 tests/webtbs/tw3827.pp svneol=native#text/plain
 tests/webtbs/tw3829.pp svneol=native#text/plain
 tests/webtbs/tw3833.pp svneol=native#text/plain

+ 10 - 8
compiler/aarch64/ncpumat.pas

@@ -82,11 +82,13 @@ implementation
          var
            helper1, helper2: TRegister;
            so: tshifterop;
+           opsize: TCgSize;
          begin
+           opsize:=def_cgsize(resultdef);
            if tordconstnode(right).value=0 then
              internalerror(2020021601)
            else if tordconstnode(right).value=1 then
-             cg.a_load_reg_reg(current_asmdata.CurrAsmList, OS_INT, OS_INT, numerator, resultreg)
+             cg.a_load_reg_reg(current_asmdata.CurrAsmList, opsize, opsize, numerator, resultreg)
            else if (tordconstnode(right).value = int64(-1)) then
              begin
                // note: only in the signed case possible..., may overflow
@@ -100,26 +102,26 @@ implementation
              begin
                if (is_signed(right.resultdef)) then
                  begin
-                    helper2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
+                    helper2:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
                     if power = 1 then
                       helper1:=numerator
                     else
                       begin
-                        helper1:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                        cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,63,numerator,helper1);
+                        helper1:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
+                        cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,opsize,resultdef.size*8-1,numerator,helper1);
                       end;
                     shifterop_reset(so);
                     so.shiftmode:=SM_LSR;
-                    so.shiftimm:=64-power;
+                    so.shiftimm:=resultdef.size*8-power;
                     current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg_shifterop(A_ADD,helper2,numerator,helper1,so));
-                    cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,power,helper2,resultreg);
+                    cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,def_cgsize(resultdef),power,helper2,resultreg);
                   end
                else
-                 cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHR,OS_INT,power,numerator,resultreg)
+                 cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHR,opsize,power,numerator,resultreg)
              end
            else
              { Everything else is handled in the generic code }
-             cg.g_div_const_reg_reg(current_asmdata.CurrAsmList,def_cgsize(resultdef),
+             cg.g_div_const_reg_reg(current_asmdata.CurrAsmList,opsize,
                tordconstnode(right).value.svalue,numerator,resultreg);
          end;
 

+ 37 - 0
tests/webtbs/tw38225.pp

@@ -0,0 +1,37 @@
+{$inline on}
+{$mode objfpc}
+uses
+  classes;
+
+operator - (const A: TPoint): TPoint; inline;
+begin
+  Result.X := - A.X;
+  Result.Y := - A.Y;
+end;
+
+operator div(const A: TPoint; ADivisor: Integer): TPoint; inline;
+begin
+  Result.X := A.X div ADivisor;
+  Result.Y := A.Y div ADivisor;
+end;
+
+
+procedure p;
+  var
+    i1,i2 : longint;
+    q1,q2 : int64;
+    d2 : dword;
+    p1,p2 : TPoint;
+
+  begin
+    p2:=-p2 div 2;
+    try
+      p2:=-p2 div 2;
+    except
+      p2:=-p2 div 2;
+    end;
+  end;
+
+begin
+end.
+