From 51e6a3f45baa5dc0cfe6bdd33d926ea244c3d405 Mon Sep 17 00:00:00 2001 From: nickysn Date: Thu, 9 Apr 2020 21:14:23 +0000 Subject: [PATCH] + implemented OP_SHL/OP_SHR/OP_SAR/OP_ROL/OP_ROR in tcgz80.a_op_reg_reg_internal git-svn-id: branches/z80@44665 - --- compiler/z80/cgcpu.pas | 143 +++++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 63 deletions(-) diff --git a/compiler/z80/cgcpu.pas b/compiler/z80/cgcpu.pas index b9fa82d297..289d806550 100644 --- a/compiler/z80/cgcpu.pas +++ b/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: