* make use of lea if possible

git-svn-id: trunk@25898 -
This commit is contained in:
florian 2013-11-01 19:01:11 +00:00
parent 945b318012
commit 3c58cad96b
2 changed files with 78 additions and 1 deletions

View File

@ -70,6 +70,9 @@ unit cgx86;
procedure a_op_ref_reg(list : TAsmList; Op: TOpCG; size: TCGSize; const ref: TReference; reg: TRegister); override;
procedure a_op_reg_ref(list : TAsmList; Op: TOpCG; size: TCGSize;reg: TRegister; const ref: TReference); override;
procedure a_op_const_reg_reg(list : TAsmList; op : Topcg; size : Tcgsize; a : tcgint; src,dst : Tregister); override;
procedure a_op_reg_reg_reg(list : TAsmList; op : TOpCg; size : tcgsize; src1,src2,dst : tregister); override;
{ move instructions }
procedure a_load_const_reg(list : TAsmList; tosize: tcgsize; a : tcgint;reg : tregister);override;
procedure a_load_const_ref(list : TAsmList; tosize: tcgsize; a : tcgint;const ref : treference);override;
@ -1547,11 +1550,71 @@ unit cgx86;
end;
procedure tcgx86.a_op_const_reg_reg(list:TAsmList;op:Topcg;size:Tcgsize;
a:tcgint;src,dst:Tregister);
var
power : longint;
href : treference;
begin
{ if (op in [OP_MUL,OP_IMUL]) and (size in [OS_32,OS_S32,OS_64,OS_S64]) and
not(cs_check_overflow in current_settings.localswitches) and
(a>1) and ispowerof2(int64(a-1),power) and (power in [1..3]) then
begin
reference_reset_base(href,src,0,0);
href.index:=src;
href.scalefactor:=a-1;
list.concat(taicpu.op_ref_reg(A_LEA,TCgSize2OpSize[size],href,dst));
end
else } if (op=OP_ADD) and
((size in [OS_32,OS_S32]) or
{ lea supports only 32 bit signed displacments }
((size=OS_64) and (a>=0) and (a<=maxLongint)) or
((size=OS_S64) and (a>=-maxLongint) and (a<=maxLongint))
) and
not(cs_check_overflow in current_settings.localswitches) then
begin
reference_reset_base(href,src,a,0);
list.concat(taicpu.op_ref_reg(A_LEA,TCgSize2OpSize[size],href,dst));
end
else if (op=OP_SUB) and
((size in [OS_32,OS_S32]) or
{ lea supports only 32 bit signed displacments }
((size=OS_64) and (a>=0) and (a<=maxLongint)) or
((size=OS_S64) and (a>=-maxLongint) and (a<=maxLongint))
) and
not(cs_check_overflow in current_settings.localswitches) then
begin
reference_reset_base(href,src,-a,0);
list.concat(taicpu.op_ref_reg(A_LEA,TCgSize2OpSize[size],href,dst));
end
else
inherited a_op_const_reg_reg(list,op,size,a,src,dst);
end;
procedure tcgx86.a_op_reg_reg_reg(list: TAsmList; op: TOpCg;
size: tcgsize; src1, src2, dst: tregister);
var
href : treference;
begin
if (op=OP_ADD) and (size in [OS_32,OS_S32,OS_64,OS_S64]) and
not(cs_check_overflow in current_settings.localswitches) then
begin
reference_reset_base(href,src1,0,0);
href.index:=src2;
list.concat(taicpu.op_ref_reg(A_LEA,TCgSize2OpSize[size],href,dst));
end
else
inherited a_op_reg_reg_reg(list,op,size,src1,src2,dst);
end;
procedure tcgx86.a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister);
var
opcode : tasmop;
power : longint;
href : treference;
{$ifdef x86_64}
tmpreg : tregister;
{$endif x86_64}
@ -1605,6 +1668,7 @@ unit cgx86;
list.concat(taicpu.op_const_reg(A_SHL,TCgSize2OpSize[size],power,reg));
exit;
end;
if op = OP_IMUL then
list.concat(taicpu.op_const_reg(A_IMUL,TCgSize2OpSize[size],a,reg))
else

View File

@ -85,6 +85,7 @@ unit nx86add;
power : longint;
hl4 : tasmlabel;
r : Tregister;
href : treference;
begin
{ at this point, left.location.loc should be LOC_REGISTER }
if right.location.loc=LOC_REGISTER then
@ -156,6 +157,18 @@ unit nx86add;
begin
emit_const_reg(A_SHL,TCGSize2Opsize[opsize],power,left.location.register);
end
else if (op=A_IMUL) and
(right.location.loc=LOC_CONSTANT) and
(right.location.value>1) and (ispowerof2(int64(right.location.value)-1,power)) and
(power in [1..3]) and
not(cs_check_overflow in current_settings.localswitches) then
begin
reference_reset_base(href,left.location.register,0,0);
href.index:=left.location.register;
href.scalefactor:=int64(right.location.value)-1;
left.location.register:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_LEA,TCgSize2OpSize[opsize],href,left.location.register));
end
else
begin
if extra_not then
@ -210,7 +223,7 @@ unit nx86add;
{ maybe we can reuse a constant register when the
operation is a comparison that doesn't change the
value of the register }
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,opdef,(nodetype in [ltn,lten,gtn,gten,equaln,unequaln]));
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,opdef,(nodetype in [ltn,lten,gtn,gten,equaln,unequaln]));
end;
end;
if (right.location.loc<>LOC_CONSTANT) and