|
@@ -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;
|
|
|
|