+ initial a_op_const_reg_reg and a_op_reg_reg_reg implementations to generate optimized 16 Bit multiplications on avr

git-svn-id: trunk@30648 -
This commit is contained in:
florian 2015-04-18 13:53:20 +00:00
parent 3e8766290d
commit 9e51283ae0

View File

@ -57,6 +57,8 @@ unit cgcpu;
procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); override;
procedure a_op_reg_reg(list: TAsmList; Op: TOpCG; size: TCGSize; src, dst : TRegister); override;
procedure a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister); override;
procedure a_op_const_reg_reg(list : TAsmList;op : TOpCg;size : tcgsize; a : tcgint;src,dst : tregister); override;
{ move instructions }
procedure a_load_const_reg(list : TAsmList; size: tcgsize; a : tcgint;reg : tregister);override;
@ -426,6 +428,47 @@ unit cgcpu;
end;
procedure tcgavr.a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister);
begin
if (op in [OP_MUL,OP_IMUL]) and (size in [OS_16,OS_S16]) then
begin
getcpuregister(list,NR_R0);
getcpuregister(list,NR_R1);
list.concat(taicpu.op_reg_reg(A_MUL,src1,src2));
emit_mov(list,dst,NR_R0);
emit_mov(list,GetNextReg(dst),NR_R1);
list.concat(taicpu.op_reg_reg(A_MUL,GetNextReg(src1),src2));
list.concat(taicpu.op_reg_reg(A_ADD,GetNextReg(dst),NR_R0));
list.concat(taicpu.op_reg_reg(A_MUL,src1,GetNextReg(src2)));
list.concat(taicpu.op_reg_reg(A_ADD,GetNextReg(dst),NR_R0));
ungetcpuregister(list,NR_R0);
list.concat(taicpu.op_reg(A_CLR,NR_R1));
ungetcpuregister(list,NR_R1);
end
else
inherited a_op_reg_reg_reg(list,op,size,src1,src2,dst);
end;
procedure tcgavr.a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister);
begin
if (op in [OP_MUL,OP_IMUL]) and (size in [OS_16,OS_S16]) and (a in [1,2,4,8]) then
begin
emit_mov(list,dst,src);
emit_mov(list,GetNextReg(dst),GetNextReg(src));
a:=a shr 1;
while a>0 do
begin
list.concat(taicpu.op_reg(A_LSL,dst));
list.concat(taicpu.op_reg(A_ROL,GetNextReg(dst)));
a:=a shr 1;
end;
end
else
inherited a_op_const_reg_reg(list,op,size,a,src,dst);
end;
procedure tcgavr.a_op_reg_reg_internal(list : TAsmList; Op: TOpCG; size: TCGSize; src, srchi, dst, dsthi: TRegister);
var
countreg,
@ -543,6 +586,19 @@ unit cgcpu;
end
else if size=OS_16 then
begin
tmpreg:=getintregister(list,OS_16);
emit_mov(list,tmpreg,dst);
emit_mov(list,GetNextReg(tmpreg),GetNextReg(dst));
list.concat(taicpu.op_reg_reg(A_MUL,tmpreg,src));
emit_mov(list,dst,NR_R0);
emit_mov(list,GetNextReg(dst),NR_R1);
list.concat(taicpu.op_reg_reg(A_MUL,GetNextReg(tmpreg),src));
list.concat(taicpu.op_reg_reg(A_ADD,GetNextReg(dst),NR_R0));
list.concat(taicpu.op_reg_reg(A_MUL,tmpreg,GetNextReg(src)));
list.concat(taicpu.op_reg_reg(A_ADD,GetNextReg(dst),NR_R0));
list.concat(taicpu.op_reg(A_CLR,NR_R1));
{ keep code for muls with overflow checking
pd:=search_system_proc('fpc_mul_word');
paraloc1.init;
paraloc2.init;
@ -568,6 +624,7 @@ unit cgcpu;
paraloc3.done;
paraloc2.done;
paraloc1.done;
}
end
else
internalerror(2011022002);
@ -1751,7 +1808,7 @@ unit cgcpu;
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));
a_op_const_reg(list,OP_SUB,countregsize,1,countreg);
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));