瀏覽代碼

+ implemented tcgz80.g_concatcopy in the general case, using the ldir instruction

git-svn-id: branches/z80@44691 -
nickysn 5 年之前
父節點
當前提交
c6a066495a
共有 1 個文件被更改,包括 25 次插入146 次删除
  1. 25 146
      compiler/z80/cgcpu.pas

+ 25 - 146
compiler/z80/cgcpu.pas

@@ -1899,7 +1899,7 @@ unit cgcpu;
 
     procedure tcgz80.g_concatcopy(list : TAsmList;const source,dest : treference;len : tcgint);
       var
-        countreg,tmpreg : tregister;
+        countreg,tmpreg,srcreg,dstreg: tregister;
         srcref,dstref : treference;
         copysize,countregsize : tcgsize;
         l : TAsmLabel;
@@ -1918,151 +1918,30 @@ unit cgcpu;
             list.concat(taicpu.op_ref_reg(A_LD,dest,tmpreg));
           end
         else
-          list.Concat(tai_comment.Create(strpnew('WARNING! not implemented: g_concatcopy')));
-        //if len>16 then
-        //  begin
-        //    current_asmdata.getjumplabel(l);
-        //
-        //    reference_reset(srcref,source.alignment,source.volatility);
-        //    reference_reset(dstref,dest.alignment,source.volatility);
-        //    srcref.base:=NR_R30;
-        //    srcref.addressmode:=AM_POSTINCREMENT;
-        //    dstref.base:=NR_R26;
-        //    dstref.addressmode:=AM_POSTINCREMENT;
-        //
-        //    copysize:=OS_8;
-        //    if len<256 then
-        //      countregsize:=OS_8
-        //    else if len<65536 then
-        //      countregsize:=OS_16
-        //    else
-        //      internalerror(2011022007);
-        //    countreg:=getintregister(list,countregsize);
-        //    a_load_const_reg(list,countregsize,len,countreg);
-        //    a_loadaddr_ref_reg(list,source,NR_R30);
-        //
-        //    { only base or index register in dest? }
-        //    if ((dest.addressmode=AM_UNCHANGED) and (dest.offset=0) and not(assigned(dest.symbol))) and
-        //      ((dest.base<>NR_NO) xor (dest.index<>NR_NO)) then
-        //      begin
-        //        if dest.base<>NR_NO then
-        //          tmpreg:=dest.base
-        //        else if dest.index<>NR_NO then
-        //          tmpreg:=dest.index
-        //        else
-        //          internalerror(2016112001);
-        //      end
-        //    else
-        //      begin
-        //        tmpreg:=getaddressregister(list);
-        //        a_loadaddr_ref_reg(list,dest,tmpreg);
-        //      end;
-        //
-        //    { X is used for spilling code so we can load it
-        //      only by a push/pop sequence, this can be
-        //      optimized later on by the peephole optimizer
-        //    }
-        //    list.concat(taicpu.op_reg(A_PUSH,tmpreg));
-        //    list.concat(taicpu.op_reg(A_PUSH,GetNextReg(tmpreg)));
-        //    list.concat(taicpu.op_reg(A_POP,NR_R27));
-        //    list.concat(taicpu.op_reg(A_POP,NR_R26));
-        //    cg.a_label(list,l);
-        //    list.concat(taicpu.op_reg_ref(GetLoad(srcref),NR_R0,srcref));
-        //    list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,NR_R0));
-        //    list.concat(taicpu.op_reg(A_DEC,countreg));
-        //    a_jmp_flags(list,F_NE,l);
-        //    // keep registers alive
-        //    list.concat(taicpu.op_reg_reg(A_MOV,countreg,countreg));
-        //  end
-        //else
-        //  begin
-        //    SrcQuickRef:=false;
-        //    DestQuickRef:=false;
-        //    if not((source.addressmode=AM_UNCHANGED) and
-        //           (source.symbol=nil) and
-        //           ((source.base=NR_R28) or
-        //            (source.base=NR_R30)) and
-        //            (source.Index=NR_NO) and
-        //            (source.Offset in [0..64-len])) and
-        //      not((source.Base=NR_NO) and (source.Index=NR_NO)) then
-        //      srcref:=normalize_ref(list,source,NR_R30)
-        //    else
-        //      begin
-        //        SrcQuickRef:=true;
-        //        srcref:=source;
-        //      end;
-        //
-        //    if not((dest.addressmode=AM_UNCHANGED) and
-        //           (dest.symbol=nil) and
-        //           ((dest.base=NR_R28) or
-        //            (dest.base=NR_R30)) and
-        //            (dest.Index=NR_No) and
-        //            (dest.Offset in [0..64-len])) and
-        //      not((dest.Base=NR_NO) and (dest.Index=NR_NO)) then
-        //      begin
-        //        if not(SrcQuickRef) then
-        //          begin
-        //            { only base or index register in dest? }
-        //            if ((dest.addressmode=AM_UNCHANGED) and (dest.offset=0) and not(assigned(dest.symbol))) and
-        //              ((dest.base<>NR_NO) xor (dest.index<>NR_NO)) then
-        //              begin
-        //                if dest.base<>NR_NO then
-        //                  tmpreg:=dest.base
-        //                else if dest.index<>NR_NO then
-        //                  tmpreg:=dest.index
-        //                else
-        //                  internalerror(2016112002);
-        //              end
-        //            else
-        //              tmpreg:=getaddressregister(list);
-        //
-        //            dstref:=normalize_ref(list,dest,tmpreg);
-        //
-        //            { X is used for spilling code so we can load it
-        //              only by a push/pop sequence, this can be
-        //              optimized later on by the peephole optimizer
-        //            }
-        //            list.concat(taicpu.op_reg(A_PUSH,tmpreg));
-        //            list.concat(taicpu.op_reg(A_PUSH,GetNextReg(tmpreg)));
-        //            list.concat(taicpu.op_reg(A_POP,NR_R27));
-        //            list.concat(taicpu.op_reg(A_POP,NR_R26));
-        //            dstref.base:=NR_R26;
-        //          end
-        //        else
-        //          dstref:=normalize_ref(list,dest,NR_R30);
-        //      end
-        //    else
-        //      begin
-        //        DestQuickRef:=true;
-        //        dstref:=dest;
-        //      end;
-        //
-        //    for i:=1 to len do
-        //      begin
-        //        if not(SrcQuickRef) and (i<len) then
-        //          srcref.addressmode:=AM_POSTINCREMENT
-        //        else
-        //          srcref.addressmode:=AM_UNCHANGED;
-        //
-        //        if not(DestQuickRef) and (i<len) then
-        //          dstref.addressmode:=AM_POSTINCREMENT
-        //        else
-        //          dstref.addressmode:=AM_UNCHANGED;
-        //
-        //        list.concat(taicpu.op_reg_ref(GetLoad(srcref),NR_R0,srcref));
-        //        list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,NR_R0));
-        //
-        //        if SrcQuickRef then
-        //          inc(srcref.offset);
-        //        if DestQuickRef then
-        //          inc(dstref.offset);
-        //      end;
-        //    if not(SrcQuickRef) then
-        //      begin
-        //        ungetcpuregister(list,srcref.base);
-        //        ungetcpuregister(list,GetNextReg(srcref.base));
-        //      end;
-        //  end;
+          begin
+            srcreg:=getintregister(list,OS_16);
+            a_loadaddr_ref_reg(list,source,srcreg);
+            dstreg:=getintregister(list,OS_16);
+            a_loadaddr_ref_reg(list,dest,dstreg);
+            getcpuregister(list,NR_L);
+            a_load_reg_reg(list,OS_8,OS_8,srcreg,NR_L);
+            getcpuregister(list,NR_H);
+            a_load_reg_reg(list,OS_8,OS_8,GetNextReg(srcreg),NR_H);
+            getcpuregister(list,NR_E);
+            a_load_reg_reg(list,OS_8,OS_8,dstreg,NR_E);
+            getcpuregister(list,NR_D);
+            a_load_reg_reg(list,OS_8,OS_8,GetNextReg(dstreg),NR_D);
+            getcpuregister(list,NR_B);
+            getcpuregister(list,NR_C);
+            list.concat(taicpu.op_reg_const(A_LD,NR_BC,len));
+            list.concat(taicpu.op_none(A_LDIR));
+            ungetcpuregister(list,NR_B);
+            ungetcpuregister(list,NR_C);
+            ungetcpuregister(list,NR_D);
+            ungetcpuregister(list,NR_E);
+            ungetcpuregister(list,NR_H);
+            ungetcpuregister(list,NR_L);
+          end;
       end;