mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-15 10:51:08 +02:00
* avr directly encodes constant shifts of 64 bit values
git-svn-id: trunk@43348 -
(cherry picked from commit f61207f1cc
)
This commit is contained in:
parent
647c5889de
commit
b241fec17b
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user