Browse Source

+ implemented OP_SHL/OP_SHR/OP_SAR/OP_ROL/OP_ROR in tcgz80.a_op_reg_reg_internal

git-svn-id: branches/z80@44665 -
nickysn 5 years ago
parent
commit
51e6a3f45b
1 changed files with 80 additions and 63 deletions
  1. 80 63
      compiler/z80/cgcpu.pas

+ 80 - 63
compiler/z80/cgcpu.pas

@@ -46,6 +46,8 @@ unit cgcpu;
 
         function getaddressregister(list:TAsmList):TRegister;override;
 
+        function GetOffsetReg64(const r,rhi: TRegister;ofs : shortint): TRegister;override;
+
         procedure a_load_const_cgpara(list : TAsmList;size : tcgsize;a : tcgint;const paraloc : TCGPara);override;
         procedure a_load_ref_cgpara(list : TAsmList;size : tcgsize;const r : treference;const cgpara : TCGPara);override;
         procedure a_loadaddr_ref_cgpara(list : TAsmList;const r : treference;const paraloc : TCGPara);override;
@@ -166,6 +168,22 @@ unit cgcpu;
       end;
 
 
+    function tcgz80.GetOffsetReg64(const r, rhi: TRegister; ofs: shortint): TRegister;
+      var
+        i: Integer;
+      begin
+        if ofs>=4 then
+          begin
+            result:=rhi;
+            dec(ofs,4);
+          end
+        else
+          result:=r;
+        for i:=1 to ofs do
+          result:=GetNextReg(result);
+      end;
+
+
     procedure tcgz80.a_load_reg_cgpara(list : TAsmList;size : tcgsize;r : tregister;const cgpara : tcgpara);
 
       procedure load_para_loc(r : TRegister;paraloc : PCGParaLocation);
@@ -697,69 +715,68 @@ unit cgcpu;
 
            OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR:
              begin
-               //current_asmdata.getjumplabel(l1);
-               //current_asmdata.getjumplabel(l2);
-               //countreg:=getintregister(list,OS_8);
-               //a_load_reg_reg(list,size,OS_8,src,countreg);
-               //list.concat(taicpu.op_reg(A_TST,countreg));
-               //a_jmp_flags(list,F_EQ,l2);
-               //cg.a_label(list,l1);
-               //case op of
-               //  OP_SHR:
-               //    list.concat(taicpu.op_reg(A_LSR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1)));
-               //  OP_SHL:
-               //    list.concat(taicpu.op_reg(A_LSL,dst));
-               //  OP_SAR:
-               //    list.concat(taicpu.op_reg(A_ASR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1)));
-               //  OP_ROR:
-               //    begin
-               //      { load carry? }
-               //      if not(size in [OS_8,OS_S8]) then
-               //        begin
-               //          list.concat(taicpu.op_none(A_CLC));
-               //          list.concat(taicpu.op_reg_const(A_SBRC,src,0));
-               //          list.concat(taicpu.op_none(A_SEC));
-               //        end;
-               //      list.concat(taicpu.op_reg(A_ROR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1)));
-               //    end;
-               //  OP_ROL:
-               //    begin
-               //      { load carry? }
-               //      if not(size in [OS_8,OS_S8]) then
-               //        begin
-               //          list.concat(taicpu.op_none(A_CLC));
-               //          list.concat(taicpu.op_reg_const(A_SBRC,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1),7));
-               //          list.concat(taicpu.op_none(A_SEC));
-               //        end;
-               //      list.concat(taicpu.op_reg(A_ROL,dst))
-               //    end;
-               //  else
-               //    internalerror(2011030901);
-               //end;
-               //if size in [OS_S16,OS_16,OS_S32,OS_32,OS_S64,OS_64] then
-               //  begin
-               //    for i:=2 to tcgsize2size[size] do
-               //      begin
-               //        case op of
-               //          OP_ROR,
-               //          OP_SHR:
-               //            list.concat(taicpu.op_reg(A_ROR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-i)));
-               //          OP_ROL,
-               //          OP_SHL:
-               //            list.concat(taicpu.op_reg(A_ROL,GetOffsetReg64(dst,dsthi,i-1)));
-               //          OP_SAR:
-               //            list.concat(taicpu.op_reg(A_ROR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-i)));
-               //          else
-               //            internalerror(2011030902);
-               //        end;
-               //    end;
-               //  end;
-               //
-               //list.concat(taicpu.op_reg(A_DEC,countreg));
-               //a_jmp_flags(list,F_NE,l1);
-               //// keep registers alive
-               //list.concat(taicpu.op_reg_reg(A_MOV,countreg,countreg));
-               //cg.a_label(list,l2);
+               current_asmdata.getjumplabel(l1);
+               current_asmdata.getjumplabel(l2);
+               getcpuregister(list,NR_B);
+               emit_mov(list,NR_B,src);
+               list.concat(taicpu.op_reg(A_INC,NR_B));
+               list.concat(taicpu.op_reg(A_DEC,NR_B));
+               a_jmp_flags(list,F_E,l2);
+               case op of
+                 OP_ROL:
+                   begin
+                     list.concat(taicpu.op_reg(A_RRC,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1)));
+                     list.concat(taicpu.op_reg(A_RLC,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1)));
+                   end;
+                 OP_ROR:
+                   begin
+                     list.concat(taicpu.op_reg(A_RLC,dst));
+                     list.concat(taicpu.op_reg(A_RRC,dst));
+                   end;
+               end;
+               cg.a_label(list,l1);
+               case op of
+                 OP_SHL:
+                   list.concat(taicpu.op_reg(A_SLA,dst));
+                 OP_SHR:
+                   list.concat(taicpu.op_reg(A_SRL,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1)));
+                 OP_SAR:
+                   list.concat(taicpu.op_reg(A_SRA,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1)));
+                 OP_ROL:
+                   if size in [OS_8,OS_S8] then
+                     list.concat(taicpu.op_reg(A_RLC,dst))
+                   else
+                     list.concat(taicpu.op_reg(A_RL,dst));
+                 OP_ROR:
+                   if size in [OS_8,OS_S8] then
+                     list.concat(taicpu.op_reg(A_RRC,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1)))
+                   else
+                     list.concat(taicpu.op_reg(A_RR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1)));
+                 else
+                   internalerror(2020040903);
+               end;
+               if size in [OS_S16,OS_16,OS_S32,OS_32,OS_S64,OS_64] then
+                 begin
+                   for i:=2 to tcgsize2size[size] do
+                     begin
+                       case op of
+                         OP_ROR,
+                         OP_SHR,
+                         OP_SAR:
+                           list.concat(taicpu.op_reg(A_RR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-i)));
+                         OP_ROL,
+                         OP_SHL:
+                           list.concat(taicpu.op_reg(A_RL,GetOffsetReg64(dst,dsthi,i-1)));
+                         else
+                           internalerror(2020040904);
+                       end;
+                   end;
+                 end;
+               instr:=taicpu.op_sym(A_DJNZ,l1);
+               instr.is_jmp:=true;
+               list.concat(instr);
+               ungetcpuregister(list,NR_B);
+               cg.a_label(list,l2);
              end;
 
            OP_AND,OP_OR,OP_XOR: