From 4010d66c2cfdb1bb57a4bbf9c2db5528c8777263 Mon Sep 17 00:00:00 2001 From: florian Date: Tue, 14 Nov 2006 22:37:22 +0000 Subject: [PATCH] * arm cond. instruction support git-svn-id: trunk@5387 - --- compiler/aopt.pas | 2 +- compiler/aoptobj.pas | 2 +- compiler/arm/aoptcpu.pas | 160 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+), 2 deletions(-) diff --git a/compiler/aopt.pas b/compiler/aopt.pas index 0dcd8ba74f..872ba40756 100644 --- a/compiler/aopt.pas +++ b/compiler/aopt.pas @@ -229,7 +229,7 @@ Unit aopt; { CSE;} End; { more peephole optimizations } - { PeepHoleOptPass2;} + PeepHoleOptPass2; { if pass = last_pass then } PostPeepHoleOpts; { free memory } diff --git a/compiler/aoptobj.pas b/compiler/aoptobj.pas index 4d5e264cc6..d8721e0848 100644 --- a/compiler/aoptobj.pas +++ b/compiler/aoptobj.pas @@ -288,7 +288,7 @@ Unit AoptObj; { peephole optimizer } procedure PrePeepHoleOpts; procedure PeepHoleOptPass1; - procedure PeepHoleOptPass2; + procedure PeepHoleOptPass2; virtual; procedure PostPeepHoleOpts; { processor dependent methods } diff --git a/compiler/arm/aoptcpu.pas b/compiler/arm/aoptcpu.pas index e15acceb04..1b2984e19f 100644 --- a/compiler/arm/aoptcpu.pas +++ b/compiler/arm/aoptcpu.pas @@ -33,10 +33,170 @@ uses cpubase, aopt, aoptcpub; Type TCpuAsmOptimizer = class(TAsmOptimizer) { uses the same constructor as TAopObj } + procedure PeepHoleOptPass2;override; End; Implementation + uses + aasmbase,aasmtai,aasmcpu; + + function CanBeCond(p : tai) : boolean; + begin + result:=true; + end; + + procedure TCpuAsmOptimizer.PeepHoleOptPass2; + var + p,hp1,hp2: tai; + l : longint; + condition : tasmcond; + hp3: tai; + { UsedRegs, TmpUsedRegs: TRegSet; } + + begin + exit; { deactived, not working yet FK } + p := BlockStart; + { UsedRegs := []; } + while (p <> BlockEnd) Do + begin + { UpdateUsedRegs(UsedRegs, tai(p.next)); } + case p.Typ Of + Ait_Instruction: + begin + case taicpu(p).opcode Of + A_B: + if taicpu(p).condition<>C_None then + begin + { check for + Bxx xxx + + xxx: + } + l:=0; + GetNextInstruction(p, hp1); + while assigned(hp1) and + (l<=4) and + CanBeCond(hp1) and + { stop on labels } + not(hp1.typ=ait_label) do + begin + inc(l); + GetNextInstruction(hp1,hp1); + end; + if assigned(hp1) then + begin + if FindLabel(tasmlabel(taicpu(p).oper[0]^.ref^.symbol),hp1) then + begin + if (l<=4) and (l>0) then + begin + condition:=inverse_cond(taicpu(p).condition); + hp2:=p; + GetNextInstruction(p,hp1); + p:=hp1; + repeat + if hp1.typ=ait_instruction then + taicpu(hp1).condition:=condition; + GetNextInstruction(hp1,hp1); + until not(assigned(hp1)) or + not(CanBeCond(hp1)) or + (hp1.typ=ait_label); + { wait with removing else GetNextInstruction could + ignore the label if it was the only usage in the + jump moved away } + tasmlabel(taicpu(hp2).oper[0]^.ref^.symbol).decrefs; + asml.remove(hp2); + hp2.free; + continue; + end; + end + else + begin + { check further for + Bcc xxx + + B yyy + xxx: + + yyy: + } + { hp2 points to jmp yyy } + hp2:=hp1; + { skip hp1 to xxx } + GetNextInstruction(hp1, hp1); + if assigned(hp2) and + assigned(hp1) and + (l<=3) and + (hp2.typ=ait_instruction) and + (taicpu(hp2).is_jmp) and + (taicpu(hp2).condition=C_None) and + { real label and jump, no further references to the + label are allowed } + (tasmlabel(taicpu(p).oper[0]^.ref^.symbol).getrefs=2) and + FindLabel(tasmlabel(taicpu(p).oper[0]^.ref^.symbol),hp1) then + begin + l:=0; + { skip hp1 to } + GetNextInstruction(hp1, hp1); + while assigned(hp1) and + CanBeCond(hp1) do + begin + inc(l); + GetNextInstruction(hp1, hp1); + end; + { hp1 points to yyy: } + if assigned(hp1) and + FindLabel(tasmlabel(taicpu(hp2).oper[0]^.ref^.symbol),hp1) then + begin + condition:=inverse_cond(taicpu(p).condition); + GetNextInstruction(p,hp1); + hp3:=p; + p:=hp1; + repeat + if hp1.typ=ait_instruction then + taicpu(hp1).condition:=condition; + GetNextInstruction(hp1,hp1); + until not(assigned(hp1)) or + not(CanBeCond(hp1)); + { hp2 is still at jmp yyy } + GetNextInstruction(hp2,hp1); + { hp2 is now at xxx: } + condition:=inverse_cond(condition); + GetNextInstruction(hp1,hp1); + { hp1 is now at } + repeat + taicpu(hp1).condition:=condition; + GetNextInstruction(hp1,hp1); + until not(assigned(hp1)) or + not(CanBeCond(hp1)) or + (hp1.typ=ait_label); + { + asml.remove(hp1.next) + hp1.next.free; + asml.remove(hp1); + hp1.free; + } + { remove Bcc } + tasmlabel(taicpu(hp3).oper[0]^.ref^.symbol).decrefs; + asml.remove(hp3); + hp3.free; + { remove jmp } + tasmlabel(taicpu(hp2).oper[0]^.ref^.symbol).decrefs; + asml.remove(hp2); + hp2.free; + continue; + end; + end; + end; + end; + end; + end; + end; + end; + p := tai(p.next) + end; + end; + begin casmoptimizer:=TCpuAsmOptimizer; End.