|
@@ -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:
|