mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-13 14:49:10 +02:00
+ JccAdd2SetccAdd optimization
* take care of C_C/C_NC in JccAdd/Inc/Dec2(Cmc)Adc/Sbb git-svn-id: trunk@44268 -
This commit is contained in:
parent
bc3131688a
commit
8f0376c888
@ -180,6 +180,7 @@ unit aoptx86;
|
||||
globals,
|
||||
cpuinfo,
|
||||
procinfo,
|
||||
paramgr,
|
||||
aasmbase,
|
||||
aoptbase,aoptutils,
|
||||
symconst,symsym,
|
||||
@ -4723,6 +4724,8 @@ unit aoptx86;
|
||||
l : Longint;
|
||||
condition : TAsmCond;
|
||||
symbol: TAsmSymbol;
|
||||
reg: tsuperregister;
|
||||
regavailable: Boolean;
|
||||
begin
|
||||
result:=false;
|
||||
symbol:=nil;
|
||||
@ -4748,7 +4751,7 @@ unit aoptx86;
|
||||
@@1: }
|
||||
begin
|
||||
carryadd_opcode:=A_NONE;
|
||||
if Taicpu(p).condition in [C_NAE,C_B] then
|
||||
if Taicpu(p).condition in [C_NAE,C_B,C_C] then
|
||||
begin
|
||||
if (Taicpu(hp1).opcode=A_INC) or
|
||||
((Taicpu(hp1).opcode=A_ADD) and
|
||||
@ -4781,7 +4784,7 @@ unit aoptx86;
|
||||
exit;
|
||||
end;
|
||||
end
|
||||
else if Taicpu(p).condition in [C_AE,C_NB] then
|
||||
else if Taicpu(p).condition in [C_AE,C_NB,C_NC] then
|
||||
begin
|
||||
if (Taicpu(hp1).opcode=A_INC) or
|
||||
((Taicpu(hp1).opcode=A_ADD) and
|
||||
@ -4810,6 +4813,77 @@ unit aoptx86;
|
||||
result:=true;
|
||||
exit;
|
||||
end;
|
||||
end
|
||||
{
|
||||
jcc @@1 setcc tmpreg
|
||||
inc/dec/add/sub operand -> (movzx tmpreg)
|
||||
@@1: add/sub tmpreg,operand
|
||||
|
||||
While this increases code size slightly, it makes the code much faster if the
|
||||
jump is unpredictable
|
||||
}
|
||||
else if not(cs_opt_size in current_settings.optimizerswitches) and
|
||||
((((Taicpu(hp1).opcode=A_ADD) or (Taicpu(hp1).opcode=A_SUB)) and
|
||||
(Taicpu(hp1).oper[0]^.typ=top_const) and
|
||||
(Taicpu(hp1).oper[1]^.typ=top_reg) and
|
||||
(Taicpu(hp1).oper[0]^.val=1)) or
|
||||
((Taicpu(hp1).opcode=A_INC) or (Taicpu(hp1).opcode=A_DEC))
|
||||
) then
|
||||
begin
|
||||
TransferUsedRegs(TmpUsedRegs);
|
||||
UpdateUsedRegs(TmpUsedRegs, tai(p.next));
|
||||
|
||||
{ search for an available register which is volatile }
|
||||
regavailable:=false;
|
||||
for reg in tcpuregisterset do
|
||||
begin
|
||||
if (reg in paramanager.get_volatile_registers_int(current_procinfo.procdef.proccalloption)) and
|
||||
not(reg in TmpUsedRegs[R_INTREGISTER].GetUsedRegs) and
|
||||
not(RegInInstruction(newreg(R_INTREGISTER,reg,R_SUBL),hp1))
|
||||
{$ifdef i386}
|
||||
and (reg in [RS_EAX,RS_EBX,RS_ECX,RS_EDX])
|
||||
{$endif i386}
|
||||
then
|
||||
begin
|
||||
regavailable:=true;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
if regavailable then
|
||||
begin
|
||||
Taicpu(p).clearop(0);
|
||||
Taicpu(p).ops:=1;
|
||||
Taicpu(p).is_jmp:=false;
|
||||
Taicpu(p).opcode:=A_SETcc;
|
||||
DebugMsg(SPeepholeOptimization+'JccAdd2SetccAdd',p);
|
||||
Taicpu(p).condition:=inverse_cond(Taicpu(p).condition);
|
||||
Taicpu(p).loadreg(0,newreg(R_INTREGISTER,reg,R_SUBL));
|
||||
|
||||
if getsubreg(Taicpu(hp1).oper[1]^.reg)<>R_SUBL then
|
||||
begin
|
||||
case getsubreg(Taicpu(hp1).oper[1]^.reg) of
|
||||
R_SUBW:
|
||||
hp2:=Taicpu.op_reg_reg(A_MOVZX,S_BW,newreg(R_INTREGISTER,reg,R_SUBL),
|
||||
newreg(R_INTREGISTER,reg,R_SUBW));
|
||||
R_SUBD,
|
||||
R_SUBQ:
|
||||
hp2:=Taicpu.op_reg_reg(A_MOVZX,S_BL,newreg(R_INTREGISTER,reg,R_SUBL),
|
||||
newreg(R_INTREGISTER,reg,R_SUBD));
|
||||
else
|
||||
Internalerror(2020030601);
|
||||
end;
|
||||
taicpu(hp2).fileinfo:=taicpu(hp1).fileinfo;
|
||||
asml.InsertAfter(hp2,p);
|
||||
end;
|
||||
if (Taicpu(hp1).opcode=A_INC) or (Taicpu(hp1).opcode=A_DEC) then
|
||||
begin
|
||||
Taicpu(hp1).ops:=2;
|
||||
Taicpu(hp1).loadoper(1,Taicpu(hp1).oper[0]^)
|
||||
end;
|
||||
Taicpu(hp1).loadreg(0,newreg(R_INTREGISTER,reg,getsubreg(Taicpu(hp1).oper[1]^.reg)));
|
||||
AllocRegBetween(newreg(R_INTREGISTER,reg,getsubreg(Taicpu(hp1).oper[1]^.reg)),p,hp1,UsedRegs);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user