فهرست منبع

* patch by Nico Erfurth:
- Support MLA and MUL in DataMov2Data
- SMLAL and UMLAL are also reading from oper[0]
- UMLAL, UMULL, SMLAL and SMULL are writing to oper[1]

git-svn-id: trunk@21421 -

florian 13 سال پیش
والد
کامیت
c348b6f2cc
1فایلهای تغییر یافته به همراه30 افزوده شده و 7 حذف شده
  1. 30 7
      compiler/arm/aoptcpu.pas

+ 30 - 7
compiler/arm/aoptcpu.pas

@@ -126,11 +126,26 @@ Implementation
     p: taicpu;
     p: taicpu;
   begin
   begin
     p := taicpu(hp);
     p := taicpu(hp);
+    regLoadedWithNewValue := false;
+    if not ((assigned(hp)) and (hp.typ = ait_instruction)) then
+      exit;
+
+    {These are not writing to their first oper}
+    if p.opcode in [A_STR, A_STRB, A_STRH, A_CMP, A_CMN, A_TST, A_TEQ,
+                        A_B, A_BL, A_BX, A_BLX] then
+      exit;
+
+    { These four are writing into the first 2 register, UMLAL and SMLAL will also read from them }
+    if (p.opcode in [A_UMLAL, A_UMULL, A_SMLAL, A_SMULL]) and
+       (p.oper[1]^.typ = top_reg) and
+       (p.oper[1]^.reg = reg) then
+    begin
+      regLoadedWithNewValue := true;
+      exit
+    end;
+
+    {All other instructions use oper[0] as destination}
     regLoadedWithNewValue :=
     regLoadedWithNewValue :=
-      (assigned(hp)) and
-      (hp.typ = ait_instruction) and
-      (not(p.opcode in [A_STR, A_STRB, A_STRH, A_CMP, A_CMN, A_TST, A_TEQ,
-                        A_B, A_BL, A_BX, A_BLX])) and
       (p.oper[0]^.typ = top_reg) and
       (p.oper[0]^.typ = top_reg) and
       (p.oper[0]^.reg = reg);
       (p.oper[0]^.reg = reg);
   end;
   end;
@@ -148,7 +163,8 @@ Implementation
     i:=1;
     i:=1;
     {For these instructions we have to start on oper[0]}
     {For these instructions we have to start on oper[0]}
     if (p.opcode in [A_STR, A_STRB, A_STRH, A_CMP, A_CMN, A_TST, A_TEQ,
     if (p.opcode in [A_STR, A_STRB, A_STRH, A_CMP, A_CMN, A_TST, A_TEQ,
-                        A_B, A_BL, A_BX, A_BLX]) then i:=0;
+                        A_B, A_BL, A_BX, A_BLX,
+                        A_SMLAL, A_UMLAL]) then i:=0;
 
 
     while(i<p.ops) do
     while(i<p.ops) do
       begin
       begin
@@ -186,7 +202,12 @@ Implementation
     begin
     begin
       if MatchInstruction(movp, A_MOV, [taicpu(p).condition], [PF_None]) and
       if MatchInstruction(movp, A_MOV, [taicpu(p).condition], [PF_None]) and
          (taicpu(movp).ops=2) and {We can't optimize if there is a shiftop}
          (taicpu(movp).ops=2) and {We can't optimize if there is a shiftop}
-         MatchOperand(taicpu(movp).oper[1]^, taicpu(p).oper[0]^.reg) then
+         MatchOperand(taicpu(movp).oper[1]^, taicpu(p).oper[0]^.reg) and
+         {There is a special requirement for MUL and MLA, oper[0] and oper[1] are not allowed to be the same}
+         not (
+           (taicpu(p).opcode in [A_MLA, A_MUL]) and
+           (taicpu(p).oper[1]^.reg = taicpu(movp).oper[0]^.reg)
+         ) then
         begin
         begin
           CopyUsedRegs(TmpUsedRegs);
           CopyUsedRegs(TmpUsedRegs);
           UpdateUsedRegs(TmpUsedRegs, tai(p.next));
           UpdateUsedRegs(TmpUsedRegs, tai(p.next));
@@ -501,7 +522,9 @@ Implementation
                 A_AND,
                 A_AND,
                 A_BIC,
                 A_BIC,
                 A_EOR,
                 A_EOR,
-                A_ORR:
+                A_ORR,
+                A_MLA,
+                A_MUL:
                   begin
                   begin
                     {
                     {
                       change
                       change