瀏覽代碼

* optimize moves into movw if possible
* use ldd instruction if possible

git-svn-id: branches/avr@17105 -

florian 14 年之前
父節點
當前提交
8f343078fa
共有 2 個文件被更改,包括 96 次插入28 次删除
  1. 37 1
      compiler/avr/aoptcpu.pas
  2. 59 27
      compiler/avr/cgcpu.pas

+ 37 - 1
compiler/avr/aoptcpu.pas

@@ -40,7 +40,7 @@ Type
 Implementation
 Implementation
 
 
   uses
   uses
-    aasmbase,aasmcpu;
+    aasmbase,aasmcpu,cgbase;
 
 
   function CanBeCond(p : tai) : boolean;
   function CanBeCond(p : tai) : boolean;
     begin
     begin
@@ -53,8 +53,44 @@ Implementation
       next1: tai;
       next1: tai;
     begin
     begin
       result := false;
       result := false;
+      case p.typ of
+        ait_instruction:
+          begin
+            case taicpu(p).opcode of
+              A_MOV:
+                begin
+                  { fold
+                    mov reg2,reg0
+                    mov reg3,reg1
+                    to
+                    movw reg2,reg0
+                  }
+                  if (taicpu(p).ops=2) and
+                     (taicpu(p).oper[0]^.typ = top_reg) and
+                     (taicpu(p).oper[1]^.typ = top_reg) and
+                     getnextinstruction(p,next1) and
+                     (next1.typ = ait_instruction) and
+                     (taicpu(next1).opcode = A_MOV) and
+                     (taicpu(next1).ops=2) and
+                     (taicpu(next1).oper[0]^.typ = top_reg) and
+                     (taicpu(next1).oper[1]^.typ = top_reg) and
+                     (getsupreg(taicpu(next1).oper[0]^.reg)=getsupreg(taicpu(p).oper[0]^.reg)+1) and
+                     ((getsupreg(taicpu(p).oper[0]^.reg) mod 2)=0) and
+                     ((getsupreg(taicpu(p).oper[1]^.reg) mod 2)=0) and
+                     (getsupreg(taicpu(next1).oper[1]^.reg)=getsupreg(taicpu(p).oper[1]^.reg)+1) then
+                    begin
+                      taicpu(p).opcode:=A_MOVW;
+                      asml.remove(next1);
+                      next1.free;
+                      result := true;
+                    end;
+                end;
+            end;
+          end;
+      end;
     end;
     end;
 
 
+
   procedure TCpuAsmOptimizer.PeepHoleOptPass2;
   procedure TCpuAsmOptimizer.PeepHoleOptPass2;
     begin
     begin
     end;
     end;

+ 59 - 27
compiler/avr/cgcpu.pas

@@ -500,7 +500,7 @@ unit cgcpu;
                     src:=GetNextReg(src);
                     src:=GetNextReg(src);
                   end;
                   end;
              end;
              end;
-          else
+           else
              internalerror(2011022004);
              internalerror(2011022004);
          end;
          end;
        end;
        end;
@@ -615,8 +615,22 @@ unit cgcpu;
          conv_done: boolean;
          conv_done: boolean;
          tmpreg : tregister;
          tmpreg : tregister;
          i : integer;
          i : integer;
+         QuickRef : Boolean;
        begin
        begin
-         href:=normalize_ref(list,Ref);
+         if not((Ref.addressmode=AM_UNCHANGED) and
+                (Ref.symbol=nil) and
+                ((Ref.base=NR_R28) or
+                 (Ref.base=NR_R29)) and
+                 (Ref.Index=NR_No) and
+                 (Ref.Offset in [0..64-tcgsize2size[tosize]])) and
+           not((Ref.Base=NR_NO) and (Ref.Index=NR_NO)) then
+           href:=normalize_ref(list,Ref)
+         else
+           begin
+             QuickRef:=true;
+             href:=Ref;
+           end;
+
          if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
          if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
            internalerror(2011021307);
            internalerror(2011021307);
 
 
@@ -629,16 +643,16 @@ unit cgcpu;
              case fromsize of
              case fromsize of
                OS_8:
                OS_8:
                  begin
                  begin
-                   if (href.base<>NR_NO) and (tcgsize2size[tosize]>1) then
+                   if not(QuickRef) and (tcgsize2size[tosize]>1) then
                      href.addressmode:=AM_POSTINCREMENT;
                      href.addressmode:=AM_POSTINCREMENT;
 
 
                    list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
                    list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
                    for i:=2 to tcgsize2size[tosize] do
                    for i:=2 to tcgsize2size[tosize] do
                      begin
                      begin
-                       if (href.offset<>0) or assigned(href.symbol) then
+                       if QuickRef then
                          inc(href.offset);
                          inc(href.offset);
 
 
-                       if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
+                       if not(QuickRef) and (i<tcgsize2size[fromsize]) then
                          href.addressmode:=AM_POSTINCREMENT
                          href.addressmode:=AM_POSTINCREMENT
                        else
                        else
                          href.addressmode:=AM_UNCHANGED;
                          href.addressmode:=AM_UNCHANGED;
@@ -648,7 +662,7 @@ unit cgcpu;
                  end;
                  end;
                OS_S8:
                OS_S8:
                  begin
                  begin
-                   if (href.base<>NR_NO) and (tcgsize2size[tosize]>1) then
+                   if not(QuickRef) and (tcgsize2size[tosize]>1) then
                      href.addressmode:=AM_POSTINCREMENT;
                      href.addressmode:=AM_POSTINCREMENT;
                    list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
                    list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
 
 
@@ -660,10 +674,10 @@ unit cgcpu;
                        list.concat(taicpu.op_reg(A_COM,tmpreg));
                        list.concat(taicpu.op_reg(A_COM,tmpreg));
                        for i:=2 to tcgsize2size[tosize] do
                        for i:=2 to tcgsize2size[tosize] do
                          begin
                          begin
-                           if (href.offset<>0) or assigned(href.symbol) then
+                           if QuickRef then
                              inc(href.offset);
                              inc(href.offset);
 
 
-                           if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
+                           if not(QuickRef) and (i<tcgsize2size[fromsize]) then
                              href.addressmode:=AM_POSTINCREMENT
                              href.addressmode:=AM_POSTINCREMENT
                            else
                            else
                              href.addressmode:=AM_UNCHANGED;
                              href.addressmode:=AM_UNCHANGED;
@@ -673,13 +687,13 @@ unit cgcpu;
                  end;
                  end;
                OS_16:
                OS_16:
                  begin
                  begin
-                   if (href.base<>NR_NO) and (tcgsize2size[tosize]>1) then
+                   if not(QuickRef) and (tcgsize2size[tosize]>1) then
                      href.addressmode:=AM_POSTINCREMENT;
                      href.addressmode:=AM_POSTINCREMENT;
 
 
                    list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
                    list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
-                   if (href.offset<>0) or assigned(href.symbol) then
+                   if QuickRef then
                      inc(href.offset)
                      inc(href.offset)
-                   else if (href.base<>NR_NO) and (tcgsize2size[fromsize]>2) then
+                   else if not(QuickRef) and (tcgsize2size[fromsize]>2) then
                      href.addressmode:=AM_POSTINCREMENT
                      href.addressmode:=AM_POSTINCREMENT
                    else
                    else
                      href.addressmode:=AM_UNCHANGED;
                      href.addressmode:=AM_UNCHANGED;
@@ -689,10 +703,10 @@ unit cgcpu;
 
 
                    for i:=3 to tcgsize2size[tosize] do
                    for i:=3 to tcgsize2size[tosize] do
                      begin
                      begin
-                       if (href.offset<>0) or assigned(href.symbol) then
+                       if QuickRef then
                          inc(href.offset);
                          inc(href.offset);
 
 
-                       if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
+                       if not(QuickRef) and (i<tcgsize2size[fromsize]) then
                          href.addressmode:=AM_POSTINCREMENT
                          href.addressmode:=AM_POSTINCREMENT
                        else
                        else
                          href.addressmode:=AM_UNCHANGED;
                          href.addressmode:=AM_UNCHANGED;
@@ -702,13 +716,13 @@ unit cgcpu;
                  end;
                  end;
                OS_S16:
                OS_S16:
                  begin
                  begin
-                   if (href.base<>NR_NO) and (tcgsize2size[tosize]>1) then
+                   if not(QuickRef) and (tcgsize2size[tosize]>1) then
                      href.addressmode:=AM_POSTINCREMENT;
                      href.addressmode:=AM_POSTINCREMENT;
 
 
                    list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
                    list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
-                   if (href.offset<>0) or assigned(href.symbol) then
+                   if QuickRef then
                      inc(href.offset)
                      inc(href.offset)
-                   else if (href.base<>NR_NO) and (tcgsize2size[fromsize]>2) then
+                   else if not(QuickRef) and (tcgsize2size[fromsize]>2) then
                      href.addressmode:=AM_POSTINCREMENT
                      href.addressmode:=AM_POSTINCREMENT
                    else
                    else
                      href.addressmode:=AM_UNCHANGED;
                      href.addressmode:=AM_UNCHANGED;
@@ -724,10 +738,10 @@ unit cgcpu;
                        list.concat(taicpu.op_reg(A_COM,tmpreg));
                        list.concat(taicpu.op_reg(A_COM,tmpreg));
                        for i:=3 to tcgsize2size[tosize] do
                        for i:=3 to tcgsize2size[tosize] do
                          begin
                          begin
-                           if (href.offset<>0) or assigned(href.symbol) then
+                           if QuickRef then
                              inc(href.offset);
                              inc(href.offset);
 
 
-                           if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
+                           if not(QuickRef) and (i<tcgsize2size[fromsize]) then
                              href.addressmode:=AM_POSTINCREMENT
                              href.addressmode:=AM_POSTINCREMENT
                            else
                            else
                              href.addressmode:=AM_UNCHANGED;
                              href.addressmode:=AM_UNCHANGED;
@@ -743,14 +757,14 @@ unit cgcpu;
            begin
            begin
              for i:=1 to tcgsize2size[fromsize] do
              for i:=1 to tcgsize2size[fromsize] do
                begin
                begin
-                   if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
+                   if not(QuickRef) and (i<tcgsize2size[fromsize]) then
                      href.addressmode:=AM_POSTINCREMENT
                      href.addressmode:=AM_POSTINCREMENT
                    else
                    else
                      href.addressmode:=AM_UNCHANGED;
                      href.addressmode:=AM_UNCHANGED;
 
 
                  list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
                  list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
 
 
-                 if (href.offset<>0) or assigned(href.symbol) then
+                 if QuickRef then
                    inc(href.offset);
                    inc(href.offset);
 
 
                  reg:=GetNextReg(reg);
                  reg:=GetNextReg(reg);
@@ -766,8 +780,22 @@ unit cgcpu;
          conv_done: boolean;
          conv_done: boolean;
          tmpreg : tregister;
          tmpreg : tregister;
          i : integer;
          i : integer;
+         QuickRef : boolean;
        begin
        begin
-         href:=normalize_ref(list,Ref);
+         if not((Ref.addressmode=AM_UNCHANGED) and
+                (Ref.symbol=nil) and
+                ((Ref.base=NR_R28) or
+                 (Ref.base=NR_R29)) and
+                 (Ref.Index=NR_No) and
+                 (Ref.Offset in [0..64-tcgsize2size[fromsize]])) and
+           not((Ref.Base=NR_NO) and (Ref.Index=NR_NO)) then
+           href:=normalize_ref(list,Ref)
+         else
+           begin
+             QuickRef:=true;
+             href:=Ref;
+           end;
+
          if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
          if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
            internalerror(2011021307);
            internalerror(2011021307);
 
 
@@ -808,11 +836,11 @@ unit cgcpu;
                  end;
                  end;
                OS_16:
                OS_16:
                  begin
                  begin
-                   if href.base<>NR_NO then
+                   if not(QuickRef) then
                      href.addressmode:=AM_POSTINCREMENT;
                      href.addressmode:=AM_POSTINCREMENT;
                    list.concat(taicpu.op_reg_ref(GetLoad(href),reg,href));
                    list.concat(taicpu.op_reg_ref(GetLoad(href),reg,href));
 
 
-                   if (href.offset<>0) or assigned(href.symbol) then
+                   if QuickRef then
                      inc(href.offset);
                      inc(href.offset);
                    href.addressmode:=AM_UNCHANGED;
                    href.addressmode:=AM_UNCHANGED;
 
 
@@ -827,10 +855,10 @@ unit cgcpu;
                  end;
                  end;
                OS_S16:
                OS_S16:
                  begin
                  begin
-                   if href.base<>NR_NO then
+                   if not(QuickRef) then
                      href.addressmode:=AM_POSTINCREMENT;
                      href.addressmode:=AM_POSTINCREMENT;
                    list.concat(taicpu.op_reg_ref(GetLoad(href),reg,href));
                    list.concat(taicpu.op_reg_ref(GetLoad(href),reg,href));
-                   if (href.offset<>0) or assigned(href.symbol) then
+                   if QuickRef then
                      inc(href.offset);
                      inc(href.offset);
                    href.addressmode:=AM_UNCHANGED;
                    href.addressmode:=AM_UNCHANGED;
 
 
@@ -857,14 +885,14 @@ unit cgcpu;
            begin
            begin
              for i:=1 to tcgsize2size[fromsize] do
              for i:=1 to tcgsize2size[fromsize] do
                begin
                begin
-                 if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
+                 if not(QuickRef) and (i<tcgsize2size[fromsize]) then
                    href.addressmode:=AM_POSTINCREMENT
                    href.addressmode:=AM_POSTINCREMENT
                  else
                  else
                    href.addressmode:=AM_UNCHANGED;
                    href.addressmode:=AM_UNCHANGED;
 
 
                  list.concat(taicpu.op_reg_ref(GetLoad(href),reg,href));
                  list.concat(taicpu.op_reg_ref(GetLoad(href),reg,href));
 
 
-                 if (href.offset<>0) or assigned(href.symbol) then
+                 if QuickRef then
                    inc(href.offset);
                    inc(href.offset);
 
 
                  reg:=GetNextReg(reg);
                  reg:=GetNextReg(reg);
@@ -1056,6 +1084,8 @@ unit cgcpu;
       begin
       begin
         if (ref.base=NR_NO) and (ref.index=NR_NO) then
         if (ref.base=NR_NO) and (ref.index=NR_NO) then
           result:=A_LDS
           result:=A_LDS
+        else if (ref.base<>NR_NO) and (ref.offset<>0) then
+          result:=A_LDD
         else
         else
           result:=A_LD;
           result:=A_LD;
       end;
       end;
@@ -1065,6 +1095,8 @@ unit cgcpu;
       begin
       begin
         if (ref.base=NR_NO) and (ref.index=NR_NO) then
         if (ref.base=NR_NO) and (ref.index=NR_NO) then
           result:=A_STS
           result:=A_STS
+        else if (ref.base<>NR_NO) and (ref.offset<>0) then
+          result:=A_STD
         else
         else
           result:=A_ST;
           result:=A_ST;
       end;
       end;