Browse Source

* remove sequential moves to the same register
+ test

git-svn-id: trunk@38267 -

florian 7 years ago
parent
commit
5eb59196d5
3 changed files with 51 additions and 0 deletions
  1. 1 0
      .gitattributes
  2. 21 0
      compiler/x86/aoptx86.pas
  3. 29 0
      tests/webtbs/tw15438.pp

+ 1 - 0
.gitattributes

@@ -14953,6 +14953,7 @@ tests/webtbs/tw1539.pp svneol=native#text/plain
 tests/webtbs/tw15391.pp svneol=native#text/plain
 tests/webtbs/tw15391a.pp svneol=native#text/plain
 tests/webtbs/tw15415.pp svneol=native#text/plain
+tests/webtbs/tw15438.pp svneol=native#text/pascal
 tests/webtbs/tw15446.pp svneol=native#text/plain
 tests/webtbs/tw15453a.pp svneol=native#text/plain
 tests/webtbs/tw15467.pp svneol=native#text/pascal

+ 21 - 0
compiler/x86/aoptx86.pas

@@ -1674,6 +1674,27 @@ unit aoptx86;
                 taicpu(hp1).fileinfo := taicpu(p).fileinfo;
                 DebugMsg(SPeepholeOptimization + 'MovMov2MovMov 1',p);
               end
+            {
+              mov*  x,reg1
+              mov*  y,reg1
+
+              to
+
+              mov*  y,reg1
+            }
+            else if (taicpu(p).oper[1]^.typ=top_reg) and
+              MatchOperand(taicpu(p).oper[1]^,taicpu(hp1).oper[1]^) and
+              not(RegInOp(taicpu(p).oper[1]^.reg,taicpu(hp1).oper[0]^)) then
+              begin
+                DebugMsg(SPeepholeOptimization + 'MovMov2Mov 4 done',p);
+                { take care of the register (de)allocs following p }
+                UpdateUsedRegs(tai(p.next));
+                asml.remove(p);
+                p.free;
+                p:=hp1;
+                Result:=true;
+                exit;
+              end;
           end
 
         else if (taicpu(p).oper[1]^.typ = top_reg) and

+ 29 - 0
tests/webtbs/tw15438.pp

@@ -0,0 +1,29 @@
+program tbSwapEndian;
+
+{$mode objfpc}
+
+uses
+    sysutils;
+
+function InlineSwapEndian(const AValue: QWord): QWord;inline;
+  begin
+    result := (qword(SwapEndian(lo(avalue))) shl 32) or SwapEndian(hi(avalue));
+  end;
+
+var
+    q : QWord;
+
+procedure Check;
+begin
+    q := $0102030405060708;
+    q := InlineSwapEndian(q);
+end;
+
+begin
+    q:=0;
+    Check;
+    if q <> $0807060504030201 then begin
+        writeln(format('failed Swap - expected $0807060504030201, got %x',[q]));
+        halt(1);
+    end;
+end.