mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-15 12:29:32 +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);
|
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
|
protected
|
||||||
procedure a_op_reg_reg_internal(list: TAsmList; Op: TOpCG; size: TCGSize; src, srchi, dst, dsthi: TRegister);
|
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 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)
|
tcg64favr = class(tcg64f32)
|
||||||
procedure a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);override;
|
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(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;
|
end;
|
||||||
|
|
||||||
procedure create_codegen;
|
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);
|
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
|
var
|
||||||
tmpSrc, tmpDst, countreg: TRegister;
|
tmpSrc, tmpDst, countreg: TRegister;
|
||||||
b, b2, i, j: byte;
|
b, b2, i, j: byte;
|
||||||
@ -478,12 +487,12 @@ unit cgcpu;
|
|||||||
for i:=0 to (tcgsize2size[size]-b-1) do
|
for i:=0 to (tcgsize2size[size]-b-1) do
|
||||||
if op=OP_SHL then
|
if op=OP_SHL then
|
||||||
a_load_reg_reg(list,OS_8,OS_8,
|
a_load_reg_reg(list,OS_8,OS_8,
|
||||||
GetOffsetReg64(src,NR_NO,i),
|
GetOffsetReg64(src,srchi,i),
|
||||||
GetOffsetReg64(dst,NR_NO,i+b))
|
GetOffsetReg64(dst,dsthi,i+b))
|
||||||
else
|
else
|
||||||
a_load_reg_reg(list,OS_8,OS_8,
|
a_load_reg_reg(list,OS_8,OS_8,
|
||||||
GetOffsetReg64(src,NR_NO,i+b),
|
GetOffsetReg64(src,srchi,i+b),
|
||||||
GetOffsetReg64(dst,NR_NO,i));
|
GetOffsetReg64(dst,dsthi,i));
|
||||||
|
|
||||||
{ remaining bit shifts }
|
{ remaining bit shifts }
|
||||||
if b2 > 0 then
|
if b2 > 0 then
|
||||||
@ -503,17 +512,17 @@ unit cgcpu;
|
|||||||
a_load_const_reg(list,OS_8,b2,countreg);
|
a_load_const_reg(list,OS_8,b2,countreg);
|
||||||
cg.a_label(list,l1);
|
cg.a_label(list,l1);
|
||||||
if op=OP_SHL then
|
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
|
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
|
if size in [OS_S16,OS_16,OS_S32,OS_32,OS_S64,OS_64] then
|
||||||
begin
|
begin
|
||||||
for i:=2+b to tcgsize2size[size] do
|
for i:=2+b to tcgsize2size[size] do
|
||||||
if op=OP_SHL then
|
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
|
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;
|
end;
|
||||||
list.concat(taicpu.op_reg(A_DEC,countreg));
|
list.concat(taicpu.op_reg(A_DEC,countreg));
|
||||||
a_jmp_flags(list,F_NE,l1);
|
a_jmp_flags(list,F_NE,l1);
|
||||||
@ -527,19 +536,19 @@ unit cgcpu;
|
|||||||
begin
|
begin
|
||||||
if op=OP_SHL then
|
if op=OP_SHL then
|
||||||
list.concat(taicpu.op_reg(A_LSL,
|
list.concat(taicpu.op_reg(A_LSL,
|
||||||
GetOffsetReg64(dst,NR_NO,b)))
|
GetOffsetReg64(dst,dsthi,b)))
|
||||||
else
|
else
|
||||||
list.concat(taicpu.op_reg(A_LSR,
|
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
|
if not(size in [OS_8,OS_S8]) then
|
||||||
for i:=2 to tcgsize2size[size]-b do
|
for i:=2 to tcgsize2size[size]-b do
|
||||||
if op=OP_SHL then
|
if op=OP_SHL then
|
||||||
list.concat(taicpu.op_reg(A_ROL,
|
list.concat(taicpu.op_reg(A_ROL,
|
||||||
GetOffsetReg64(dst,NR_NO,b+i-1)))
|
GetOffsetReg64(dst,dsthi,b+i-1)))
|
||||||
else
|
else
|
||||||
list.concat(taicpu.op_reg(A_ROR,
|
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;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -548,9 +557,9 @@ unit cgcpu;
|
|||||||
Do last,then optimizer can optimize register moves }
|
Do last,then optimizer can optimize register moves }
|
||||||
for i:=1 to b do
|
for i:=1 to b do
|
||||||
if op=OP_SHL then
|
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
|
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
|
end
|
||||||
else
|
else
|
||||||
inherited a_op_const_reg_reg(list,op,size,a,src,dst);
|
inherited a_op_const_reg_reg(list,op,size,a,src,dst);
|
||||||
@ -2849,6 +2858,15 @@ unit cgcpu;
|
|||||||
end;
|
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;
|
procedure create_codegen;
|
||||||
begin
|
begin
|
||||||
cg:=tcgavr.create;
|
cg:=tcgavr.create;
|
||||||
|
@ -34,7 +34,9 @@ interface
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
tavrshlshrnode = class(tcgshlshrnode)
|
tavrshlshrnode = class(tcgshlshrnode)
|
||||||
|
function pass_1: tnode;override;
|
||||||
procedure second_integer;override;
|
procedure second_integer;override;
|
||||||
|
procedure second_64bit;override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -46,7 +48,7 @@ implementation
|
|||||||
aasmbase,aasmcpu,aasmtai,aasmdata,
|
aasmbase,aasmcpu,aasmtai,aasmdata,
|
||||||
defutil,
|
defutil,
|
||||||
cgbase,cgobj,hlcgobj,cgutils,
|
cgbase,cgobj,hlcgobj,cgutils,
|
||||||
pass_2,procinfo,
|
pass_1,pass_2,procinfo,
|
||||||
ncon,
|
ncon,
|
||||||
cpubase,
|
cpubase,
|
||||||
ncgutil,cgcpu;
|
ncgutil,cgcpu;
|
||||||
@ -129,6 +131,28 @@ implementation
|
|||||||
end;
|
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;
|
procedure tavrshlshrnode.second_integer;
|
||||||
var
|
var
|
||||||
op : topcg;
|
op : topcg;
|
||||||
@ -152,7 +176,13 @@ implementation
|
|||||||
(left.location.size<>opsize) then
|
(left.location.size<>opsize) then
|
||||||
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,opdef,true);
|
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,opdef,true);
|
||||||
location_reset(location,LOC_REGISTER,opsize);
|
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: }
|
{ shifting by a constant directly coded: }
|
||||||
if (right.nodetype=ordconstn) then
|
if (right.nodetype=ordconstn) then
|
||||||
@ -164,8 +194,12 @@ implementation
|
|||||||
shiftval:=tordconstnode(right).value.uvalue and 31
|
shiftval:=tordconstnode(right).value.uvalue and 31
|
||||||
else
|
else
|
||||||
shiftval:=tordconstnode(right).value.uvalue and 63;
|
shiftval:=tordconstnode(right).value.uvalue and 63;
|
||||||
hlcg.a_op_const_reg_reg(current_asmdata.CurrAsmList,op,opdef,
|
if is_64bit(resultdef) then
|
||||||
shiftval,left.location.register,location.register);
|
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
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -186,6 +220,13 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tavrshlshrnode.second_64bit;
|
||||||
|
begin
|
||||||
|
second_integer;
|
||||||
|
// inherited second_64bit;
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
cnotnode:=tavrnotnode;
|
cnotnode:=tavrnotnode;
|
||||||
cshlshrnode:=tavrshlshrnode;
|
cshlshrnode:=tavrshlshrnode;
|
||||||
|
Loading…
Reference in New Issue
Block a user