mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-02 00:10:31 +02:00
+ Add optimization to optimize [0..31]-x set expression to use one less
register. This construction is used in our Shootout meteor contest implementation. git-svn-id: trunk@7176 -
This commit is contained in:
parent
83f6a8f612
commit
ea79e69176
@ -334,11 +334,14 @@ unit nx86add;
|
||||
op : TAsmOp;
|
||||
extra_not,
|
||||
noswap : boolean;
|
||||
all_member_optimization:boolean;
|
||||
|
||||
begin
|
||||
pass_left_right;
|
||||
|
||||
noswap:=false;
|
||||
extra_not:=false;
|
||||
all_member_optimization:=false;
|
||||
opsize:=int_cgsize(resultdef.size);
|
||||
case nodetype of
|
||||
addn :
|
||||
@ -371,6 +374,10 @@ unit nx86add;
|
||||
subn :
|
||||
begin
|
||||
op:=A_AND;
|
||||
if (not(nf_swapped in flags) and (left.location.loc=LOC_CONSTANT) and (left.location.value=-1)) or
|
||||
((nf_swapped in flags) and (right.location.loc=LOC_CONSTANT) and (right.location.value=-1)) then
|
||||
all_member_optimization:=true;
|
||||
|
||||
if (not(nf_swapped in flags)) and
|
||||
(right.location.loc=LOC_CONSTANT) then
|
||||
right.location.value := not(right.location.value)
|
||||
@ -389,13 +396,30 @@ unit nx86add;
|
||||
else
|
||||
internalerror(2003042215);
|
||||
end;
|
||||
{ left must be a register }
|
||||
left_must_be_reg(opsize,noswap);
|
||||
emit_generic_code(op,opsize,true,extra_not,false);
|
||||
location_freetemp(current_asmdata.CurrAsmList,right.location);
|
||||
if all_member_optimization then
|
||||
begin
|
||||
{ right.location is a LOC_REGISTER }
|
||||
{ when swapped another result register }
|
||||
if nf_swapped in flags then
|
||||
begin
|
||||
{ newly swapped also set swapped flag }
|
||||
location_swap(left.location,right.location);
|
||||
toggleflag(nf_swapped);
|
||||
end;
|
||||
location_force_reg(current_asmdata.currAsmList,right.location,opsize,false);
|
||||
emit_reg(A_NOT,TCGSize2Opsize[opsize],right.location.register);
|
||||
location:=right.location;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ left must be a register }
|
||||
left_must_be_reg(opsize,noswap);
|
||||
emit_generic_code(op,opsize,true,extra_not,false);
|
||||
location_freetemp(current_asmdata.CurrAsmList,right.location);
|
||||
|
||||
{ left is always a register and contains the result }
|
||||
location:=left.location;
|
||||
{ left is always a register and contains the result }
|
||||
location:=left.location;
|
||||
end;
|
||||
|
||||
{ fix the changed opsize we did above because of the missing btsb }
|
||||
if opsize<>int_cgsize(resultdef.size) then
|
||||
|
Loading…
Reference in New Issue
Block a user