mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 15:49:26 +02:00
Generalize skip instruction optimization for both sbix and sbrx.
git-svn-id: trunk@42154 -
This commit is contained in:
parent
833e00bfbd
commit
c867d2b7f6
@ -42,6 +42,8 @@ Type
|
||||
function RegLoadedWithNewValue(reg : tregister; hp : tai) : boolean; override;
|
||||
function InstructionLoadsFromReg(const reg : TRegister; const hp : tai) : boolean; override;
|
||||
|
||||
function InvertSkipInstruction(var p: tai): boolean;
|
||||
|
||||
{ uses the same constructor as TAopObj }
|
||||
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
|
||||
procedure PeepHoleOptPass2;override;
|
||||
@ -225,6 +227,71 @@ Implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{
|
||||
Turns
|
||||
sbis ?
|
||||
jmp .Lx
|
||||
op
|
||||
.Lx:
|
||||
|
||||
Into
|
||||
sbic ?
|
||||
op
|
||||
|
||||
For all types of skip instructions
|
||||
}
|
||||
function TCpuAsmOptimizer.InvertSkipInstruction(var p: tai): boolean;
|
||||
|
||||
function GetNextInstructionWithoutLabel(p: tai; var next: tai): boolean;
|
||||
begin
|
||||
repeat
|
||||
result:=GetNextInstruction(p,next);
|
||||
p:=next;
|
||||
until
|
||||
(not result) or
|
||||
(not assigned(next)) or
|
||||
(next.typ in [ait_instruction]);
|
||||
|
||||
result:=assigned(next) and (next.typ in [ait_instruction]);
|
||||
end;
|
||||
|
||||
var
|
||||
hp1, hp2, hp3: tai;
|
||||
s: string;
|
||||
begin
|
||||
result:=false;
|
||||
|
||||
if GetNextInstruction(taicpu(p),hp1) and
|
||||
(hp1.typ=ait_instruction) and
|
||||
(taicpu(hp1).opcode in [A_RJMP,A_JMP]) and
|
||||
(taicpu(hp1).ops=1) and
|
||||
(taicpu(hp1).oper[0]^.typ=top_ref) and
|
||||
(taicpu(hp1).oper[0]^.ref^.offset=0) and
|
||||
(taicpu(hp1).oper[0]^.ref^.symbol is TAsmLabel) and
|
||||
GetNextInstructionWithoutLabel(hp1,hp2) and
|
||||
(hp2.typ=ait_instruction) and
|
||||
(not taicpu(hp2).is_jmp) and
|
||||
GetNextInstruction(hp2,hp3) and
|
||||
FindLabel(TAsmLabel(taicpu(hp1).oper[0]^.ref^.symbol),hp3) then
|
||||
begin
|
||||
DebugMsg('SkipJump2InvertedSkip', p);
|
||||
|
||||
case taicpu(p).opcode of
|
||||
A_SBIS: taicpu(p).opcode:=A_SBIC;
|
||||
A_SBIC: taicpu(p).opcode:=A_SBIS;
|
||||
A_SBRS: taicpu(p).opcode:=A_SBRC;
|
||||
A_SBRC: taicpu(p).opcode:=A_SBRS;
|
||||
end;
|
||||
|
||||
TAsmLabel(taicpu(hp1).oper[0]^.ref^.symbol).decrefs;
|
||||
|
||||
asml.remove(hp1);
|
||||
hp1.free;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
|
||||
var
|
||||
hp1,hp2,hp3,hp4,hp5: tai;
|
||||
@ -520,6 +587,9 @@ Implementation
|
||||
|
||||
result:=true;
|
||||
end;
|
||||
|
||||
if InvertSkipInstruction(p) then
|
||||
result:=true;
|
||||
end;
|
||||
A_ANDI:
|
||||
begin
|
||||
@ -1023,33 +1093,8 @@ Implementation
|
||||
op
|
||||
.L1:
|
||||
}
|
||||
if GetNextInstruction(p, hp1) and
|
||||
(hp1.typ=ait_instruction) and
|
||||
(taicpu(hp1).opcode in [A_JMP,A_RJMP]) and
|
||||
(taicpu(hp1).ops>0) and
|
||||
(taicpu(hp1).oper[0]^.typ = top_ref) and
|
||||
(taicpu(hp1).oper[0]^.ref^.symbol is TAsmLabel) and
|
||||
GetNextInstruction(hp1, hp2) and
|
||||
(hp2.typ=ait_instruction) and
|
||||
(not taicpu(hp2).is_jmp) and
|
||||
GetNextInstruction(hp2, hp3) and
|
||||
(hp3.typ=ait_label) and
|
||||
(taicpu(hp1).oper[0]^.ref^.symbol=tai_label(hp3).labsym) then
|
||||
begin
|
||||
DebugMsg('Peephole SbiJmp2Sbi performed',p);
|
||||
|
||||
if taicpu(p).opcode=A_SBIC then
|
||||
taicpu(p).opcode:=A_SBIS
|
||||
else
|
||||
taicpu(p).opcode:=A_SBIC;
|
||||
|
||||
tai_label(hp3).labsym.decrefs;
|
||||
|
||||
AsmL.remove(hp1);
|
||||
taicpu(hp1).Free;
|
||||
|
||||
result:=true;
|
||||
end
|
||||
if InvertSkipInstruction(p) then
|
||||
result:=true
|
||||
{
|
||||
Turn
|
||||
sbiX X, y
|
||||
|
Loading…
Reference in New Issue
Block a user