Prechádzať zdrojové kódy

* avoid shifter constant overflow on arm when optimizing two shifter operations into one

git-svn-id: trunk@11474 -
florian 17 rokov pred
rodič
commit
66e015f48c
3 zmenil súbory, kde vykonal 33 pridanie a 0 odobranie
  1. 1 0
      .gitattributes
  2. 20 0
      compiler/arm/aoptcpu.pas
  3. 12 0
      tests/test/opt/tarmshift.pp

+ 1 - 0
.gitattributes

@@ -7446,6 +7446,7 @@ tests/test/cg/variants/tvarol96.pp svneol=native#text/plain
 tests/test/dumpclass.pp svneol=native#text/plain
 tests/test/dumpclass.pp svneol=native#text/plain
 tests/test/dumpmethods.pp svneol=native#text/plain
 tests/test/dumpmethods.pp svneol=native#text/plain
 tests/test/opt/README -text
 tests/test/opt/README -text
+tests/test/opt/tarmshift.pp svneol=native#text/plain
 tests/test/opt/tcaseopt1.pp svneol=native#text/plain
 tests/test/opt/tcaseopt1.pp svneol=native#text/plain
 tests/test/opt/tcmov.pp svneol=native#text/plain
 tests/test/opt/tcmov.pp svneol=native#text/plain
 tests/test/opt/tcse1.pp svneol=native#text/plain
 tests/test/opt/tcse1.pp svneol=native#text/plain

+ 20 - 0
compiler/arm/aoptcpu.pas

@@ -40,6 +40,7 @@ Type
 Implementation
 Implementation
 
 
   uses
   uses
+    verbose,
     aasmbase,aasmcpu;
     aasmbase,aasmcpu;
 
 
   function CanBeCond(p : tai) : boolean;
   function CanBeCond(p : tai) : boolean;
@@ -51,6 +52,7 @@ Implementation
   function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
   function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
     var
     var
       next1: tai;
       next1: tai;
+      hp1: tai;
     begin
     begin
       result := false;
       result := false;
       case p.typ of
       case p.typ of
@@ -82,6 +84,24 @@ Implementation
                      (taicpu(p).oper[2]^.shifterop^.shiftmode=taicpu(next1).oper[2]^.shifterop^.shiftmode) then
                      (taicpu(p).oper[2]^.shifterop^.shiftmode=taicpu(next1).oper[2]^.shifterop^.shiftmode) then
                     begin
                     begin
                       inc(taicpu(p).oper[2]^.shifterop^.shiftimm,taicpu(next1).oper[2]^.shifterop^.shiftimm);
                       inc(taicpu(p).oper[2]^.shifterop^.shiftimm,taicpu(next1).oper[2]^.shifterop^.shiftimm);
+                      { avoid overflows }
+                      if taicpu(p).oper[2]^.shifterop^.shiftimm>31 then
+                        case taicpu(p).oper[2]^.shifterop^.shiftmode of
+                          SM_ROR:
+                            taicpu(p).oper[2]^.shifterop^.shiftimm:=taicpu(p).oper[2]^.shifterop^.shiftimm and 31;
+                          SM_ASR:
+                            taicpu(p).oper[2]^.shifterop^.shiftimm:=31;
+                          SM_LSR,
+                          SM_LSL:
+                            begin
+                              hp1:=taicpu.op_reg_const(A_MOV,taicpu(p).oper[0]^.reg,0);
+                              InsertLLItem(p.previous, p.next, hp1);
+                              p.free;
+                              p:=hp1;
+                            end;
+                          else
+                            internalerror(2008072803);
+                        end;
                       asml.remove(next1);
                       asml.remove(next1);
                       next1.free;
                       next1.free;
                       result := true;
                       result := true;

+ 12 - 0
tests/test/opt/tarmshift.pp

@@ -0,0 +1,12 @@
+{ %norun }
+{ %opt=-O2 }
+var
+  i : longint;
+
+begin
+  i:=1234;
+  i:=i shl 23;
+  i:=i shl 23;
+  if i<>0 then
+    halt(1);
+end.