浏览代码

* fix avr for new GetNextReg behaviour
* some wrong GetNextReg usage in the avr code generator fixed

git-svn-id: trunk@37316 -

florian 7 年之前
父节点
当前提交
9ef646e3c5
共有 2 个文件被更改,包括 77 次插入22 次删除
  1. 69 20
      compiler/avr/cgcpu.pas
  2. 8 2
      compiler/cgobj.pas

+ 69 - 20
compiler/avr/cgcpu.pas

@@ -266,7 +266,9 @@ unit cgcpu;
                   begin
                     load_para_loc(r,hp);
                     hp:=hp^.Next;
-                    r:=GetNextReg(r);
+                    { check if we are not in the last iteration to avoid an internalerror in GetNextReg }
+                    if i<tcgsize2size[cgpara.Size] then
+                      r:=GetNextReg(r);
                   end
                 else
                   begin
@@ -481,7 +483,8 @@ unit cgcpu;
          l1,l2 : tasmlabel;
          pd : tprocdef;
 
-       procedure NextSrcDst;
+      { NextRegDst* is sometimes called before the register usage and sometimes afterwards }
+       procedure NextSrcDstPreInc;
          begin
            if i=5 then
              begin
@@ -495,10 +498,24 @@ unit cgcpu;
              end;
          end;
 
+       procedure NextSrcDstPostInc;
+         begin
+           if i=4 then
+             begin
+               dst:=dsthi;
+               src:=srchi;
+             end
+           else
+             begin
+               dst:=GetNextReg(dst);
+               src:=GetNextReg(src);
+             end;
+         end;
+
        { iterates TmpReg through all registers of dst }
        procedure NextTmp;
          begin
-           if i=5 then
+           if i=4 then
              tmpreg:=dsthi
            else
              tmpreg:=GetNextReg(tmpreg);
@@ -513,7 +530,7 @@ unit cgcpu;
                  begin
                    for i:=2 to tcgsize2size[size] do
                      begin
-                       NextSrcDst;
+                       NextSrcDstPreInc;
                        list.concat(taicpu.op_reg_reg(A_ADC,dst,src));
                      end;
                  end;
@@ -526,7 +543,7 @@ unit cgcpu;
                  begin
                    for i:=2 to tcgsize2size[size] do
                      begin
-                       NextSrcDst;
+                       NextSrcDstPreInc;
                        list.concat(taicpu.op_reg_reg(A_SBC,dst,src));
                      end;
                  end;
@@ -551,14 +568,18 @@ unit cgcpu;
                    for i:=2 to tcgsize2size[size] do
                      begin
                        list.concat(taicpu.op_reg(A_COM,tmpreg));
-                       NextTmp;
+                       { check if we are not in the last iteration to avoid an internalerror in GetNextReg }
+                       if i<tcgsize2size[size] then
+                         NextTmp;
                      end;
                    list.concat(taicpu.op_reg(A_NEG,dst));
                    tmpreg:=GetNextReg(dst);
                    for i:=2 to tcgsize2size[size] do
                      begin
                        list.concat(taicpu.op_reg_const(A_SBCI,tmpreg,-1));
-                       NextTmp;
+                       { check if we are not in the last iteration to avoid an internalerror in GetNextReg }
+                       if i<tcgsize2size[size] then
+                         NextTmp;
                    end;
                  end;
              end;
@@ -570,7 +591,9 @@ unit cgcpu;
                    if src<>dst then
                      a_load_reg_reg(list,OS_8,OS_8,src,dst);
                    list.concat(taicpu.op_reg(A_COM,dst));
-                   NextSrcDst;
+                   { check if we are not in the last iteration to avoid an internalerror in GetNextReg }
+                   if i<tcgsize2size[size] then
+                     NextSrcDstPostInc;
                  end;
              end;
 
@@ -719,7 +742,9 @@ unit cgcpu;
                 for i:=1 to tcgsize2size[size] do
                   begin
                     list.concat(taicpu.op_reg_reg(topcg2asmop[op],dst,src));
-                    NextSrcDst;
+                    { check if we are not in the last iteration to avoid an internalerror in GetNextReg }
+                    if i<tcgsize2size[size] then
+                      NextSrcDstPostInc;
                   end;
              end;
            else
@@ -737,7 +762,8 @@ unit cgcpu;
          tmpreg : tregister;
          tmpreg64 : tregister64;
 
-      procedure NextReg;
+      { NextReg* is sometimes called before the register usage and sometimes afterwards }
+      procedure NextRegPreInc;
         begin
           if i=5 then
             reg:=reghi
@@ -745,6 +771,15 @@ unit cgcpu;
             reg:=GetNextReg(reg);
         end;
 
+
+      procedure NextRegPostInc;
+        begin
+          if i=4 then
+            reg:=reghi
+          else
+            reg:=GetNextReg(reg);
+        end;
+
       var
         curvalue : byte;
         l1: TAsmLabel;
@@ -769,7 +804,9 @@ unit cgcpu;
                  begin
                    if ((qword(a) and mask) shr shift)<>0 then
                      list.concat(taicpu.op_reg_const(A_ORI,reg,(qword(a) and mask) shr shift));
-                   NextReg;
+                   { check if we are not in the last iteration to avoid an internalerror in GetNextReg }
+                   if i<tcgsize2size[size] then
+                     NextRegPostInc;
                    mask:=mask shl 8;
                    inc(shift,8);
                  end;
@@ -782,7 +819,9 @@ unit cgcpu;
                      list.concat(taicpu.op_reg_reg(A_MOV,reg,NR_R1))
                    else
                      list.concat(taicpu.op_reg_const(A_ANDI,reg,(qword(a) and mask) shr shift));
-                   NextReg;
+                   { check if we are not in the last iteration to avoid an internalerror in GetNextReg }
+                   if i<tcgsize2size[size] then
+                     NextRegPostInc;
                    mask:=mask shl 8;
                    inc(shift,8);
                  end;
@@ -797,7 +836,7 @@ unit cgcpu;
                  begin
                    for i:=2 to tcgsize2size[size] do
                      begin
-                       NextReg;
+                       NextRegPreInc;
                        mask:=mask shl 8;
                        inc(shift,8);
                        curvalue:=(qword(a) and mask) shr shift;
@@ -914,7 +953,7 @@ unit cgcpu;
                  begin
                    for i:=2 to tcgsize2size[size] do
                      begin
-                       NextReg;
+                       NextRegPreInc;
                        mask:=mask shl 8;
                        inc(shift,8);
                        curvalue:=(qword(a) and mask) shr shift;
@@ -988,7 +1027,9 @@ unit cgcpu;
 
              mask:=mask shl 8;
              inc(shift,8);
-             reg:=GetNextReg(reg);
+             { check if we are not in the last iteration to avoid an internalerror in GetNextReg }
+             if i<tcgsize2size[size] then
+               reg:=GetNextReg(reg);
            end;
        end;
 
@@ -1288,7 +1329,9 @@ unit cgcpu;
                  if QuickRef then
                    inc(href.offset);
 
-                 reg:=GetNextReg(reg);
+                 { check if we are not in the last iteration to avoid an internalerror in GetNextReg }
+                 if i<tcgsize2size[fromsize] then
+                   reg:=GetNextReg(reg);
                end;
            end;
 
@@ -1442,7 +1485,9 @@ unit cgcpu;
                  if QuickRef then
                    inc(href.offset);
 
-                 reg:=GetNextReg(reg);
+                 { check if we are not in the last iteration to avoid an internalerror in GetNextReg }
+                 if i<tcgsize2size[fromsize] then
+                   reg:=GetNextReg(reg);
                end;
            end;
 
@@ -1542,8 +1587,12 @@ unit cgcpu;
              for i:=1 to tcgsize2size[fromsize] do
                begin
                  emit_mov(list,reg2,reg1);
-                 reg1:=GetNextReg(reg1);
-                 reg2:=GetNextReg(reg2);
+                 { check if we are not in the last iteration to avoid an internalerror in GetNextReg }
+                 if i<tcgsize2size[fromsize] then
+                   begin
+                     reg1:=GetNextReg(reg1);
+                     reg2:=GetNextReg(reg2);
+                   end;
                end;
            end;
        end;
@@ -2168,7 +2217,7 @@ unit cgcpu;
             if not(SrcQuickRef) then
               begin
                 ungetcpuregister(list,srcref.base);
-                ungetcpuregister(list,GetNextReg(srcref.base));
+                ungetcpuregister(list,TRegister(ord(srcref.base)+1));
               end;
           end;
       end;

+ 8 - 2
compiler/cgobj.pas

@@ -731,14 +731,20 @@ implementation
 {$if defined(cpu8bitalu) or defined(cpu16bitalu)}
     function tcg.GetNextReg(const r: TRegister): TRegister;
       begin
+{$ifndef AVR}
+        { the AVR code generator depends on the fact that it can do GetNextReg also on physical registers }
         if getsupreg(r)<first_int_imreg then
           internalerror(2013051401);
+        if not has_next_reg[getsupreg(r)] then
+          internalerror(2017091103);
+{$else AVR}
+        if (getsupreg(r)>=first_int_imreg) and not(has_next_reg[getsupreg(r)]) then
+          internalerror(2017091103);
+{$endif AVR}
         if getregtype(r)<>R_INTREGISTER then
           internalerror(2017091101);
         if getsubreg(r)<>R_SUBWHOLE then
           internalerror(2017091102);
-        if not has_next_reg[getsupreg(r)] then
-          internalerror(2017091103);
         result:=TRegister(longint(r)+1);
       end;
 {$endif cpu8bitalu or cpu16bitalu}