mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 06:09:22 +02:00
* arm: New Bcc; CMP; Bcc -> CMP(~c); Bcc optimisation
This commit is contained in:
parent
bea36238e7
commit
88433ca273
@ -76,6 +76,7 @@ Type
|
|||||||
{ Individual optimisation routines }
|
{ Individual optimisation routines }
|
||||||
function OptPass1DataCheckMov(var p: tai): Boolean;
|
function OptPass1DataCheckMov(var p: tai): Boolean;
|
||||||
function OptPass1ADDSUB(var p: tai): Boolean;
|
function OptPass1ADDSUB(var p: tai): Boolean;
|
||||||
|
function OptPass1Bcc(var p: tai): Boolean;
|
||||||
function OptPass1CMP(var p: tai): Boolean;
|
function OptPass1CMP(var p: tai): Boolean;
|
||||||
function OptPass1STM(var p: tai): Boolean;
|
function OptPass1STM(var p: tai): Boolean;
|
||||||
function OptPass1MOV(var p: tai): Boolean;
|
function OptPass1MOV(var p: tai): Boolean;
|
||||||
@ -811,6 +812,60 @@ Implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TCpuAsmOptimizer.OptPass1Bcc(var p: tai): Boolean;
|
||||||
|
var
|
||||||
|
hp1, hp2, hp_last: tai;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
|
||||||
|
{ Change:
|
||||||
|
b(c) @Lbl
|
||||||
|
cmp ## (also cmn, tst and teq)
|
||||||
|
b(c) @Lbl (same label)
|
||||||
|
|
||||||
|
To:
|
||||||
|
cmp(~c) ##
|
||||||
|
b(c) @Lbl
|
||||||
|
}
|
||||||
|
if (taicpu(p).condition <> C_None) and
|
||||||
|
IsJumpToLabel(taicpu(p)) and
|
||||||
|
GetNextInstruction(p, hp1) and
|
||||||
|
(hp1.typ = ait_instruction) then
|
||||||
|
begin
|
||||||
|
if (
|
||||||
|
(cs_opt_size in current_settings.optimizerswitches) or
|
||||||
|
{ Too many chained conditional CMPs will cause slowdown }
|
||||||
|
(
|
||||||
|
GetLastInstruction(p, hp_last) and
|
||||||
|
(
|
||||||
|
{ Permit if previous entry is either not an instruction or is
|
||||||
|
unconditional (e.g. a regular CMP) }
|
||||||
|
(hp_last.typ <> ait_instruction) or
|
||||||
|
(taicpu(hp_last).condition = C_None)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) and
|
||||||
|
MatchInstruction(hp1, [A_CMP, A_CMN, A_TST, A_TEQ], [C_None], [PF_None]) and
|
||||||
|
GetNextInstruction(hp1, hp2) and
|
||||||
|
{ Conditions must match }
|
||||||
|
MatchInstruction(hp2, [A_B], [taicpu(p).condition], [PF_None]) and
|
||||||
|
{ Make sure jumps go to the same destination }
|
||||||
|
references_equal(JumpTargetOp(taicpu(p))^.ref^, JumpTargetOp(taicpu(hp2))^.ref^) then
|
||||||
|
begin
|
||||||
|
DebugMsg(SPeepholeOptimization + 'Bcc; CMP; Bcc -> CMP(~c); Bcc', p);
|
||||||
|
{ Apply inverted condition to the comparison, thus preserving the
|
||||||
|
flags if the inverted condition is not fulfilled }
|
||||||
|
taicpu(hp1).condition := inverse_cond(taicpu(p).condition);
|
||||||
|
JumpTargetOp(taicpu(p))^.ref^.symbol.decrefs;
|
||||||
|
AllocRegBetween(NR_DEFAULTFLAGS, p, hp1, UsedRegs);
|
||||||
|
RemoveCurrentP(p, hp1);
|
||||||
|
Result := True;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TCpuAsmOptimizer.OptPass1CMP(var p: tai): Boolean;
|
function TCpuAsmOptimizer.OptPass1CMP(var p: tai): Boolean;
|
||||||
var
|
var
|
||||||
hp1, hp2, hp_last: tai;
|
hp1, hp2, hp_last: tai;
|
||||||
@ -2343,6 +2398,8 @@ Implementation
|
|||||||
if p.typ = ait_instruction then
|
if p.typ = ait_instruction then
|
||||||
begin
|
begin
|
||||||
case taicpu(p).opcode of
|
case taicpu(p).opcode of
|
||||||
|
A_B:
|
||||||
|
Result := OptPass1Bcc(p);
|
||||||
A_CMP:
|
A_CMP:
|
||||||
Result := OptPass1CMP(p);
|
Result := OptPass1CMP(p);
|
||||||
A_STR:
|
A_STR:
|
||||||
|
Loading…
Reference in New Issue
Block a user