* avr directly encodes constant shifts of 64 bit values

git-svn-id: trunk@43348 -
(cherry picked from commit f61207f1cc)
This commit is contained in:
florian 2019-11-01 18:39:15 +00:00
parent 647c5889de
commit b241fec17b
2 changed files with 77 additions and 18 deletions

View File

@ -114,6 +114,8 @@ unit cgcpu;
procedure gen_multiply(list: TAsmList; op: topcg; size: TCgSize; src2, src1, dst: tregister; check_overflow: boolean; var ovloc: tlocation);
private
procedure a_op_const_reg_reg_internal(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, srchi, dst, dsthi: tregister);
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);
@ -123,6 +125,7 @@ unit cgcpu;
tcg64favr = class(tcg64f32)
procedure a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);override;
procedure a_op64_const_reg(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);override;
procedure a_op64_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; value: int64;src,dst: tregister64);override;
end;
procedure create_codegen;
@ -438,6 +441,12 @@ unit cgcpu;
procedure tcgavr.a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister);
begin
a_op_const_reg_reg_internal(list,op,size,a,src,NR_NO,dst,NR_NO);
end;
procedure tcgavr.a_op_const_reg_reg_internal(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src,srchi,dst,dsthi: tregister);
var
tmpSrc, tmpDst, countreg: TRegister;
b, b2, i, j: byte;
@ -478,12 +487,12 @@ unit cgcpu;
for i:=0 to (tcgsize2size[size]-b-1) do
if op=OP_SHL then
a_load_reg_reg(list,OS_8,OS_8,
GetOffsetReg64(src,NR_NO,i),
GetOffsetReg64(dst,NR_NO,i+b))
GetOffsetReg64(src,srchi,i),
GetOffsetReg64(dst,dsthi,i+b))
else
a_load_reg_reg(list,OS_8,OS_8,
GetOffsetReg64(src,NR_NO,i+b),
GetOffsetReg64(dst,NR_NO,i));
GetOffsetReg64(src,srchi,i+b),
GetOffsetReg64(dst,dsthi,i));
{ remaining bit shifts }
if b2 > 0 then
@ -503,17 +512,17 @@ unit cgcpu;
a_load_const_reg(list,OS_8,b2,countreg);
cg.a_label(list,l1);
if op=OP_SHL then
list.concat(taicpu.op_reg(A_LSL,GetOffsetReg64(dst,NR_NO,b)))
list.concat(taicpu.op_reg(A_LSL,GetOffsetReg64(dst,dsthi,b)))
else
list.concat(taicpu.op_reg(A_LSR,GetOffsetReg64(dst,NR_NO,tcgsize2size[size]-1-b)));
list.concat(taicpu.op_reg(A_LSR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1-b)));
if size in [OS_S16,OS_16,OS_S32,OS_32,OS_S64,OS_64] then
begin
for i:=2+b to tcgsize2size[size] do
if op=OP_SHL then
list.concat(taicpu.op_reg(A_ROL,GetOffsetReg64(dst,NR_NO,i-1)))
list.concat(taicpu.op_reg(A_ROL,GetOffsetReg64(dst,dsthi,i-1)))
else
list.concat(taicpu.op_reg(A_ROR,GetOffsetReg64(dst,NR_NO,tcgsize2size[size]-i)));
list.concat(taicpu.op_reg(A_ROR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-i)));
end;
list.concat(taicpu.op_reg(A_DEC,countreg));
a_jmp_flags(list,F_NE,l1);
@ -527,19 +536,19 @@ unit cgcpu;
begin
if op=OP_SHL then
list.concat(taicpu.op_reg(A_LSL,
GetOffsetReg64(dst,NR_NO,b)))
GetOffsetReg64(dst,dsthi,b)))
else
list.concat(taicpu.op_reg(A_LSR,
GetOffsetReg64(dst,NR_NO,tcgsize2size[size]-b-1)));
GetOffsetReg64(dst,dsthi,tcgsize2size[size]-b-1)));
if not(size in [OS_8,OS_S8]) then
for i:=2 to tcgsize2size[size]-b do
if op=OP_SHL then
list.concat(taicpu.op_reg(A_ROL,
GetOffsetReg64(dst,NR_NO,b+i-1)))
GetOffsetReg64(dst,dsthi,b+i-1)))
else
list.concat(taicpu.op_reg(A_ROR,
GetOffsetReg64(dst,NR_NO,tcgsize2size[size]-b-i)));
GetOffsetReg64(dst,dsthi,tcgsize2size[size]-b-i)));
end;
end;
end;
@ -548,9 +557,9 @@ unit cgcpu;
Do last,then optimizer can optimize register moves }
for i:=1 to b do
if op=OP_SHL then
emit_mov(list,GetOffsetReg64(dst,NR_NO,i-1),NR_R1)
emit_mov(list,GetOffsetReg64(dst,dsthi,i-1),NR_R1)
else
emit_mov(list,GetOffsetReg64(dst,NR_NO,tcgsize2size[size]-i),NR_R1);
emit_mov(list,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-i),NR_R1);
end
else
inherited a_op_const_reg_reg(list,op,size,a,src,dst);
@ -2849,6 +2858,15 @@ unit cgcpu;
end;
procedure tcg64favr.a_op64_const_reg_reg(list: TAsmList; op: TOpCg;size: tcgsize;value: int64;src,dst : tregister64);
begin
if op in [OP_SHL,OP_SHR] then
tcgavr(cg).a_op_const_reg_reg_internal(list,Op,size,value,src.reglo,src.reghi,dst.reglo,dst.reghi)
else
Inherited a_op64_const_reg_reg(list,op,size,value,src,dst);
end;
procedure create_codegen;
begin
cg:=tcgavr.create;

View File

@ -34,7 +34,9 @@ interface
end;
tavrshlshrnode = class(tcgshlshrnode)
function pass_1: tnode;override;
procedure second_integer;override;
procedure second_64bit;override;
end;
implementation
@ -46,7 +48,7 @@ implementation
aasmbase,aasmcpu,aasmtai,aasmdata,
defutil,
cgbase,cgobj,hlcgobj,cgutils,
pass_2,procinfo,
pass_1,pass_2,procinfo,
ncon,
cpubase,
ncgutil,cgcpu;
@ -129,6 +131,28 @@ implementation
end;
{*****************************************************************************
TAVRSHLSHRNODE
*****************************************************************************}
function tavrshlshrnode.pass_1 : tnode;
begin
{ the avr code generator can handle 64 bit shifts by constants directly }
if is_constintnode(right) and is_64bit(resultdef) then
begin
result:=nil;
firstpass(left);
firstpass(right);
if codegenerror then
exit;
expectloc:=LOC_REGISTER;
end
else
Result:=inherited pass_1;
end;
procedure tavrshlshrnode.second_integer;
var
op : topcg;
@ -152,7 +176,13 @@ implementation
(left.location.size<>opsize) then
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,opdef,true);
location_reset(location,LOC_REGISTER,opsize);
location.register:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef);
if is_64bit(resultdef) then
begin
location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
location.registerhi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
end
else
location.register:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef);
{ shifting by a constant directly coded: }
if (right.nodetype=ordconstn) then
@ -164,8 +194,12 @@ implementation
shiftval:=tordconstnode(right).value.uvalue and 31
else
shiftval:=tordconstnode(right).value.uvalue and 63;
hlcg.a_op_const_reg_reg(current_asmdata.CurrAsmList,op,opdef,
shiftval,left.location.register,location.register);
if is_64bit(resultdef) then
cg64.a_op64_const_reg_reg(current_asmdata.CurrAsmList,op,location.size,
shiftval,left.location.register64,location.register64)
else
hlcg.a_op_const_reg_reg(current_asmdata.CurrAsmList,op,opdef,
shiftval,left.location.register,location.register);
end
else
begin
@ -186,6 +220,13 @@ implementation
end;
end;
procedure tavrshlshrnode.second_64bit;
begin
second_integer;
// inherited second_64bit;
end;
begin
cnotnode:=tavrnotnode;
cshlshrnode:=tavrshlshrnode;