+ implemented OP_MUL/OP_IMUL in tcgz80.a_op_reg_reg_internal

git-svn-id: branches/z80@45105 -
This commit is contained in:
nickysn 2020-04-26 16:37:53 +00:00
parent 78c40a6d70
commit 05ca71133f

View File

@ -119,6 +119,7 @@ unit cgcpu;
protected
procedure a_op_reg_reg_internal(list: TAsmList; Op: TOpCG; size: TCGSize; src, srchi, dst, dsthi: TRegister);
procedure a_op_const_reg_internal(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg, reghi: TRegister);
procedure gen_multiply(list: TAsmList; op: topcg; size: TCgSize; src2, src1, dst: tregister; check_overflow: boolean);
procedure maybegetcpuregister(list : tasmlist; reg : tregister);
end;
@ -848,10 +849,13 @@ unit cgcpu;
OP_MUL,OP_IMUL:
begin
{ special stuff, needs separate handling inside code
generator }
list.Concat(tai_comment.Create(strpnew('WARNING! not implemented: a_op_reg_reg_internal OP_MUL/OP_IMUL')));
{internalerror(2017032604);}
tmpreg:=dst;
if size in [OS_16,OS_S16] then
begin
tmpreg:=getintregister(list,size);
a_load_reg_reg(list,size,size,dst,tmpreg);
end;
gen_multiply(list,op,size,src,tmpreg,dst,false);
end;
OP_DIV,OP_IDIV:
@ -1260,6 +1264,78 @@ unit cgcpu;
end;
procedure tcgz80.gen_multiply(list: TAsmList; op: topcg; size: TCgSize; src2, src1, dst: tregister; check_overflow: boolean);
var
pd: tprocdef;
paraloc1, paraloc2: tcgpara;
ai: taicpu;
hl, no_overflow: TAsmLabel;
name: String;
begin
if size in [OS_8,OS_S8] then
begin
if size=OS_8 then
name:='fpc_mul_byte'
else
name:='fpc_mul_shortint';
if check_overflow then
name:=name+'_checkoverflow';
pd:=search_system_proc(name);
paraloc1.init;
paraloc2.init;
paramanager.getcgtempparaloc(list,pd,1,paraloc1);
paramanager.getcgtempparaloc(list,pd,2,paraloc2);
a_load_reg_cgpara(list,OS_8,src1,paraloc2);
a_load_reg_cgpara(list,OS_8,src2,paraloc1);
paramanager.freecgpara(list,paraloc2);
paramanager.freecgpara(list,paraloc1);
alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
a_call_name(list,upper(name),false);
dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
cg.a_reg_alloc(list,NR_L);
cg.a_load_reg_reg(list,OS_8,OS_8,NR_L,dst);
cg.a_reg_dealloc(list,NR_L);
paraloc2.done;
paraloc1.done;
end
else if size in [OS_16,OS_S16] then
begin
if size=OS_16 then
name:='fpc_mul_word'
else
name:='fpc_mul_integer';
if check_overflow then
name:=name+'_checkoverflow';
pd:=search_system_proc(name);
paraloc1.init;
paraloc2.init;
paramanager.getcgtempparaloc(list,pd,1,paraloc1);
paramanager.getcgtempparaloc(list,pd,2,paraloc2);
a_load_reg_cgpara(list,OS_16,src1,paraloc2);
a_load_reg_cgpara(list,OS_16,src2,paraloc1);
paramanager.freecgpara(list,paraloc2);
paramanager.freecgpara(list,paraloc1);
alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
a_call_name(list,upper(name),false);
dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
cg.a_reg_alloc(list,NR_L);
cg.a_reg_alloc(list,NR_H);
cg.a_load_reg_reg(list,OS_8,OS_8,NR_L,dst);
cg.a_reg_dealloc(list,NR_L);
cg.a_load_reg_reg(list,OS_8,OS_8,NR_H,GetNextReg(dst));
cg.a_reg_dealloc(list,NR_H);
paraloc2.done;
paraloc1.done;
end
else
internalerror(2011022002);
end;
procedure tcgz80.a_load_const_reg(list : TAsmList; size: tcgsize; a : tcgint;reg : tregister);
var
mask : qword;