mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-10 02:28:22 +02:00
* fixed generic jumps optimizer and enabled it for ppc (the label table
was not being initialised -> getfinaldestination always failed, which caused wrong optimizations in some cases) * changed the inverse_cond into a function, because tasmcond is a record on ppc + added a compare_conditions() function for the same reason
This commit is contained in:
parent
126f3fa6cf
commit
ec959955bd
@ -43,8 +43,10 @@ Unit aopt;
|
||||
Destructor destroy;override;
|
||||
|
||||
private
|
||||
Function FindLoHiLabels: tai;
|
||||
procedure FindLoHiLabels;
|
||||
Procedure BuildLabelTableAndFixRegAlloc;
|
||||
procedure clear;
|
||||
procedure pass_1;
|
||||
End;
|
||||
|
||||
var
|
||||
@ -63,20 +65,21 @@ Unit aopt;
|
||||
inherited create(_asml,nil,nil,nil);
|
||||
{setup labeltable, always necessary}
|
||||
New(LabelInfo);
|
||||
End;
|
||||
|
||||
procedure TAsmOptimizer.FindLoHiLabels;
|
||||
{ Walks through the paasmlist to find the lowest and highest label number. }
|
||||
{ Returns the last Pai object of the current block }
|
||||
Var LabelFound: Boolean;
|
||||
p, prev: tai;
|
||||
Begin
|
||||
LabelInfo^.LowLabel := High(AWord);
|
||||
LabelInfo^.HighLabel := 0;
|
||||
LabelInfo^.LabelDif := 0;
|
||||
LabelInfo^.LabelTable:=nil;
|
||||
End;
|
||||
|
||||
Function TAsmOptimizer.FindLoHiLabels: tai;
|
||||
{ Walks through the paasmlist to find the lowest and highest label number. }
|
||||
{ Returns the last Pai object of the current block }
|
||||
Var LabelFound: Boolean;
|
||||
p: tai;
|
||||
Begin
|
||||
LabelFound := False;
|
||||
P := BlockStart;
|
||||
prev := p;
|
||||
With LabelInfo^ Do
|
||||
Begin
|
||||
While Assigned(P) And
|
||||
@ -92,9 +95,13 @@ Unit aopt;
|
||||
If (tai_Label(p).l.labelnr > HighLabel) Then
|
||||
HighLabel := tai_Label(p).l.labelnr
|
||||
End;
|
||||
prev := p;
|
||||
GetNextInstruction(p, p)
|
||||
End;
|
||||
FindLoHiLabels := p;
|
||||
if (prev.typ = ait_marker) and
|
||||
(tai_marker(prev).kind = asmblockstart) then
|
||||
blockend := prev
|
||||
else blockend := nil;
|
||||
If LabelFound
|
||||
Then LabelDif := HighLabel-LowLabel+1
|
||||
Else LabelDif := 0
|
||||
@ -160,15 +167,30 @@ Unit aopt;
|
||||
End
|
||||
};
|
||||
End
|
||||
End
|
||||
End;
|
||||
P := tai(p.Next);
|
||||
While Assigned(p) and
|
||||
(p <> blockend) and
|
||||
(p.typ in (SkipInstr - [ait_regalloc])) Do
|
||||
P := tai(P.Next)
|
||||
End;
|
||||
P := tai(p.Next);
|
||||
While Assigned(p) And
|
||||
(p.typ in (SkipInstr - [ait_regalloc])) Do
|
||||
P := tai(P.Next)
|
||||
End
|
||||
End;
|
||||
|
||||
procedure tasmoptimizer.clear;
|
||||
begin
|
||||
if LabelInfo^.labeldif <> 0 then
|
||||
begin
|
||||
freemem(LabelInfo^.labeltable);
|
||||
LabelInfo^.labeltable := nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure tasmoptimizer.pass_1;
|
||||
begin
|
||||
findlohilabels;
|
||||
BuildLabelTableAndFixRegAlloc;
|
||||
end;
|
||||
|
||||
|
||||
Procedure TAsmOptimizer.Optimize;
|
||||
@ -178,6 +200,7 @@ Unit aopt;
|
||||
Begin
|
||||
pass:=0;
|
||||
BlockStart := tai(AsmL.First);
|
||||
pass_1;
|
||||
While Assigned(BlockStart) Do
|
||||
Begin
|
||||
if pass = 0 then
|
||||
@ -189,20 +212,16 @@ Unit aopt;
|
||||
PeepHoleOptPass1;
|
||||
If (cs_slowoptimize in aktglobalswitches) Then
|
||||
Begin
|
||||
// DFA:=TAOptDFACpu.Create(AsmL,BlockStart,BlockEnd,LabelInfo);
|
||||
// DFA:=TAOptDFACpu.Create(AsmL,BlockStart,BlockEnd,LabelInfo);
|
||||
{ data flow analyzer }
|
||||
DFA.DoDFA;
|
||||
// DFA.DoDFA;
|
||||
{ common subexpression elimination }
|
||||
{ CSE;}
|
||||
End;
|
||||
{ more peephole optimizations }
|
||||
{ PeepHoleOptPass2;}
|
||||
{dispose labeltabel}
|
||||
If Assigned(LabelInfo^.LabelTable) Then
|
||||
Begin
|
||||
Dispose(LabelInfo^.LabelTable);
|
||||
LabelInfo := Nil
|
||||
End;
|
||||
{ free memory }
|
||||
clear;
|
||||
{ continue where we left off, BlockEnd is either the start of an }
|
||||
{ assembler block or nil}
|
||||
BlockStart := BlockEnd;
|
||||
@ -210,20 +229,20 @@ Unit aopt;
|
||||
(BlockStart.typ = ait_Marker) And
|
||||
(tai_Marker(BlockStart).Kind = AsmBlockStart) Do
|
||||
Begin
|
||||
{ we stopped at an assembler block, so skip it }
|
||||
While GetNextInstruction(BlockStart, BlockStart) And
|
||||
((BlockStart.Typ <> Ait_Marker) Or
|
||||
(tai_Marker(Blockstart).Kind <> AsmBlockEnd)) Do;
|
||||
{ we stopped at an assembler block, so skip it }
|
||||
While GetNextInstruction(BlockStart, BlockStart) And
|
||||
((BlockStart.Typ <> Ait_Marker) Or
|
||||
(tai_Marker(Blockstart).Kind <> AsmBlockEnd)) Do;
|
||||
{ blockstart now contains a tai_marker(asmblockend) }
|
||||
If Not(GetNextInstruction(BlockStart, HP) And
|
||||
((HP.typ <> ait_Marker) Or
|
||||
(tai_Marker(HP).Kind <> AsmBlockStart)
|
||||
)
|
||||
) Then
|
||||
{skip the next assembler block }
|
||||
BlockStart := HP;
|
||||
{ otherwise there is no assembler block anymore after the current }
|
||||
{ one, so optimize the next block of "normal" instructions }
|
||||
If GetNextInstruction(BlockStart, HP) And
|
||||
((HP.typ <> ait_Marker) Or
|
||||
(Tai_Marker(HP).Kind <> AsmBlockStart)) Then
|
||||
{ There is no assembler block anymore after the current one, so }
|
||||
{ optimize the next block of "normal" instructions }
|
||||
pass_1
|
||||
{ Otherwise, skip the next assembler block }
|
||||
else
|
||||
blockStart := hp;
|
||||
End
|
||||
End;
|
||||
End;
|
||||
@ -252,7 +271,15 @@ end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.9 2005-02-14 17:13:06 peter
|
||||
Revision 1.10 2005-02-26 01:26:59 jonas
|
||||
* fixed generic jumps optimizer and enabled it for ppc (the label table
|
||||
was not being initialised -> getfinaldestination always failed, which
|
||||
caused wrong optimizations in some cases)
|
||||
* changed the inverse_cond into a function, because tasmcond is a record
|
||||
on ppc
|
||||
+ added a compare_conditions() function for the same reason
|
||||
|
||||
Revision 1.9 2005/02/14 17:13:06 peter
|
||||
* truncate log
|
||||
|
||||
}
|
||||
|
@ -919,17 +919,19 @@ Unit AoptObj;
|
||||
(taicpu(p1).is_jmp) then
|
||||
if { the next instruction after the label where the jump hp arrives}
|
||||
{ is unconditional or of the same type as hp, so continue }
|
||||
(taicpu(p1).condition in [C_None,hp.condition]) or
|
||||
((taicpu(p1).opcode = aopt_uncondjmp) or
|
||||
conditions_equal(taicpu(p1).condition,hp.condition)) or
|
||||
{ the next instruction after the label where the jump hp arrives}
|
||||
{ is the opposite of hp (so this one is never taken), but after }
|
||||
{ that one there is a branch that will be taken, so perform a }
|
||||
{ little hack: set p1 equal to this instruction (that's what the}
|
||||
{ last SkipLabels is for, only works with short bool evaluation)}
|
||||
((taicpu(p1).condition = inverse_cond[hp.condition]) and
|
||||
(conditions_equal(taicpu(p1).condition,inverse_cond(hp.condition)) and
|
||||
SkipLabels(p1,p2) and
|
||||
(p2.typ = ait_instruction) and
|
||||
(taicpu(p2).is_jmp) and
|
||||
(taicpu(p2).condition in [C_None,hp.condition]) and
|
||||
((taicpu(p2).opcode = aopt_uncondjmp) or
|
||||
(conditions_equal(taicpu(p2).condition,hp.condition))) and
|
||||
SkipLabels(p1,p1)) then
|
||||
begin
|
||||
{ quick check for loops of the form "l5: ; jmp l5 }
|
||||
@ -943,7 +945,7 @@ Unit AoptObj;
|
||||
tasmlabel(hp.oper[0]^.ref^.symbol).increfs;
|
||||
end
|
||||
else
|
||||
if (taicpu(p1).condition = inverse_cond[hp.condition]) then
|
||||
if conditions_equal(taicpu(p1).condition,inverse_cond(hp.condition)) then
|
||||
if not FindAnyLabel(p1,l) then
|
||||
begin
|
||||
{$ifdef finaldestdebug}
|
||||
@ -1034,7 +1036,7 @@ Unit AoptObj;
|
||||
begin
|
||||
if taicpu(p).opcode=aopt_condjmp then
|
||||
begin
|
||||
taicpu(p).condition:=inverse_cond[taicpu(p).condition];
|
||||
taicpu(p).condition:=inverse_cond(taicpu(p).condition);
|
||||
tai_label(hp2).l.decrefs;
|
||||
taicpu(p).oper[0]^.ref^.symbol:=taicpu(hp1).oper[0]^.ref^.symbol;
|
||||
taicpu(p).oper[0]^.ref^.symbol.increfs;
|
||||
@ -1085,7 +1087,15 @@ End.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.16 2005-02-25 20:50:53 jonas
|
||||
Revision 1.17 2005-02-26 01:26:59 jonas
|
||||
* fixed generic jumps optimizer and enabled it for ppc (the label table
|
||||
was not being initialised -> getfinaldestination always failed, which
|
||||
caused wrong optimizations in some cases)
|
||||
* changed the inverse_cond into a function, because tasmcond is a record
|
||||
on ppc
|
||||
+ added a compare_conditions() function for the same reason
|
||||
|
||||
Revision 1.16 2005/02/25 20:50:53 jonas
|
||||
* fixed uninitialised function result in getfinaldestination() when
|
||||
maximum recursion reached
|
||||
|
||||
|
@ -934,7 +934,7 @@ unit cgcpu;
|
||||
ai : taicpu;
|
||||
begin
|
||||
list.concat(setcondition(taicpu.op_reg_const(A_MOV,reg,1),flags_to_cond(f)));
|
||||
list.concat(setcondition(taicpu.op_reg_const(A_MOV,reg,0),inverse_cond[flags_to_cond(f)]));
|
||||
list.concat(setcondition(taicpu.op_reg_const(A_MOV,reg,0),inverse_cond(flags_to_cond(f))));
|
||||
end;
|
||||
|
||||
|
||||
@ -1688,7 +1688,15 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.71 2005-02-16 22:02:26 florian
|
||||
Revision 1.72 2005-02-26 01:26:59 jonas
|
||||
* fixed generic jumps optimizer and enabled it for ppc (the label table
|
||||
was not being initialised -> getfinaldestination always failed, which
|
||||
caused wrong optimizations in some cases)
|
||||
* changed the inverse_cond into a function, because tasmcond is a record
|
||||
on ppc
|
||||
+ added a compare_conditions() function for the same reason
|
||||
|
||||
Revision 1.71 2005/02/16 22:02:26 florian
|
||||
* fixed storing of floating point registers for procedures with large temp. area
|
||||
* fixed int64 comparisation
|
||||
|
||||
|
@ -186,11 +186,6 @@ unit cpubase;
|
||||
'GE','LT','GT','LE','AL','NV'
|
||||
);
|
||||
|
||||
inverse_cond : array[TAsmCond] of TAsmCond=(C_None,
|
||||
C_NE,C_EQ,C_CC,C_CS,C_PL,C_MI,C_VC,C_VS,C_LS,C_HI,
|
||||
C_LT,C_GE,C_LE,C_GT,C_None,C_None
|
||||
);
|
||||
|
||||
{*****************************************************************************
|
||||
Flags
|
||||
*****************************************************************************}
|
||||
@ -385,6 +380,9 @@ unit cpubase;
|
||||
function std_regnum_search(const s:string):Tregister;
|
||||
function std_regname(r:Tregister):string;
|
||||
|
||||
function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
|
||||
procedure shifterop_reset(var so : tshifterop);
|
||||
function is_pc(const r : tregister) : boolean;
|
||||
|
||||
@ -494,10 +492,36 @@ unit cpubase;
|
||||
is_pc:=(r=NR_R15);
|
||||
end;
|
||||
|
||||
|
||||
function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
const
|
||||
inverse: array[TAsmCond] of TAsmCond=(C_None,
|
||||
C_NE,C_EQ,C_CC,C_CS,C_PL,C_MI,C_VC,C_VS,C_LS,C_HI,
|
||||
C_LT,C_GE,C_LE,C_GT,C_None,C_None
|
||||
);
|
||||
begin
|
||||
result := inverse[c];
|
||||
end;
|
||||
|
||||
|
||||
function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
begin
|
||||
result := c1 = c2;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.38 2005-02-14 17:13:09 peter
|
||||
Revision 1.39 2005-02-26 01:26:59 jonas
|
||||
* fixed generic jumps optimizer and enabled it for ppc (the label table
|
||||
was not being initialised -> getfinaldestination always failed, which
|
||||
caused wrong optimizations in some cases)
|
||||
* changed the inverse_cond into a function, because tasmcond is a record
|
||||
on ppc
|
||||
+ added a compare_conditions() function for the same reason
|
||||
|
||||
Revision 1.38 2005/02/14 17:13:09 peter
|
||||
* truncate log
|
||||
|
||||
}
|
||||
|
@ -73,8 +73,6 @@
|
||||
{$ifdef powerpc}
|
||||
{$define cpuflags}
|
||||
{$define cputargethasfixedstack}
|
||||
{$define noopt}
|
||||
{define oldregvars}
|
||||
{$endif powerpc}
|
||||
|
||||
{$ifdef arm}
|
||||
@ -95,7 +93,15 @@
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.49 2005-02-14 17:13:06 peter
|
||||
Revision 1.50 2005-02-26 01:26:59 jonas
|
||||
* fixed generic jumps optimizer and enabled it for ppc (the label table
|
||||
was not being initialised -> getfinaldestination always failed, which
|
||||
caused wrong optimizations in some cases)
|
||||
* changed the inverse_cond into a function, because tasmcond is a record
|
||||
on ppc
|
||||
+ added a compare_conditions() function for the same reason
|
||||
|
||||
Revision 1.49 2005/02/14 17:13:06 peter
|
||||
* truncate log
|
||||
|
||||
Revision 1.48 2005/02/08 22:33:51 olle
|
||||
|
@ -483,7 +483,7 @@ var
|
||||
{ that one there is a branch that will be taken, so perform a }
|
||||
{ little hack: set p1 equal to this instruction (that's what the}
|
||||
{ last SkipLabels is for, only works with short bool evaluation)}
|
||||
((taicpu(p1).condition = inverse_cond[hp.condition]) and
|
||||
((taicpu(p1).condition = inverse_cond(hp.condition)) and
|
||||
SkipLabels(p1,p2) and
|
||||
(p2.typ = ait_instruction) and
|
||||
(taicpu(p2).is_jmp) and
|
||||
@ -501,7 +501,7 @@ var
|
||||
tasmlabel(hp.oper[0]^.ref^.symbol).increfs;
|
||||
end
|
||||
else
|
||||
if (taicpu(p1).condition = inverse_cond[hp.condition]) then
|
||||
if (taicpu(p1).condition = inverse_cond(hp.condition)) then
|
||||
if not FindAnyLabel(p1,l) then
|
||||
begin
|
||||
{$ifdef finaldestdebug}
|
||||
@ -627,7 +627,7 @@ begin
|
||||
begin
|
||||
if taicpu(p).opcode=A_Jcc then
|
||||
begin
|
||||
taicpu(p).condition:=inverse_cond[taicpu(p).condition];
|
||||
taicpu(p).condition:=inverse_cond(taicpu(p).condition);
|
||||
tai_label(hp2).l.decrefs;
|
||||
taicpu(p).oper[0]^.ref^.symbol:=taicpu(hp1).oper[0]^.ref^.symbol;
|
||||
taicpu(p).oper[0]^.ref^.symbol.increfs;
|
||||
@ -1673,7 +1673,7 @@ begin
|
||||
begin
|
||||
if (l<=4) and (l>0) then
|
||||
begin
|
||||
condition:=inverse_cond[taicpu(p).condition];
|
||||
condition:=inverse_cond(taicpu(p).condition);
|
||||
GetNextInstruction(p,hp1);
|
||||
asml.remove(p);
|
||||
p.free;
|
||||
@ -1723,7 +1723,7 @@ begin
|
||||
if assigned(hp1) and
|
||||
FindLabel(tasmlabel(taicpu(hp2).oper[0]^.sym),hp1) then
|
||||
begin
|
||||
condition:=inverse_cond[taicpu(p).condition];
|
||||
condition:=inverse_cond(taicpu(p).condition;
|
||||
GetNextInstruction(p,hp1);
|
||||
asml.remove(p);
|
||||
p.free;
|
||||
@ -1735,7 +1735,7 @@ begin
|
||||
until not(assigned(hp1)) or
|
||||
not(CanBeCMOV(hp1));
|
||||
hp2:=hp1.next;
|
||||
condition:=inverse_cond[condition];
|
||||
condition:=inverse_cond(condition);
|
||||
|
||||
asml.remove(hp1.next)
|
||||
hp1.next.free;
|
||||
@ -2003,7 +2003,15 @@ end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.68 2005-02-25 20:50:53 jonas
|
||||
Revision 1.69 2005-02-26 01:27:00 jonas
|
||||
* fixed generic jumps optimizer and enabled it for ppc (the label table
|
||||
was not being initialised -> getfinaldestination always failed, which
|
||||
caused wrong optimizations in some cases)
|
||||
* changed the inverse_cond into a function, because tasmcond is a record
|
||||
on ppc
|
||||
+ added a compare_conditions() function for the same reason
|
||||
|
||||
Revision 1.68 2005/02/25 20:50:53 jonas
|
||||
* fixed uninitialised function result in getfinaldestination() when
|
||||
maximum recursion reached
|
||||
|
||||
|
@ -27,19 +27,31 @@ Unit aoptcpu;
|
||||
|
||||
Interface
|
||||
|
||||
uses cpubase, aoptobj, aoptcpub;
|
||||
{$i fpcdefs.inc}
|
||||
|
||||
uses cpubase, aoptobj, aoptcpub, aopt;
|
||||
|
||||
Type
|
||||
TAOptCpu = Object(TAoptObj)
|
||||
TCpuAsmOptimizer = class(TAsmOptimizer)
|
||||
{ uses the same constructor as TAopObj }
|
||||
End;
|
||||
|
||||
Implementation
|
||||
|
||||
begin
|
||||
casmoptimizer:=TCpuAsmOptimizer;
|
||||
End.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.6 2005-02-14 17:13:10 peter
|
||||
Revision 1.7 2005-02-26 01:27:00 jonas
|
||||
* fixed generic jumps optimizer and enabled it for ppc (the label table
|
||||
was not being initialised -> getfinaldestination always failed, which
|
||||
caused wrong optimizations in some cases)
|
||||
* changed the inverse_cond into a function, because tasmcond is a record
|
||||
on ppc
|
||||
+ added a compare_conditions() function for the same reason
|
||||
|
||||
Revision 1.6 2005/02/14 17:13:10 peter
|
||||
* truncate log
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,8 @@
|
||||
}
|
||||
Unit aoptcpub; { Assembler OPTimizer CPU specific Base }
|
||||
|
||||
{$i fpcdefs.inc}
|
||||
|
||||
{ enable the following define if memory references can have both a base and }
|
||||
{ index register in 1 operand }
|
||||
|
||||
@ -41,7 +43,7 @@ Unit aoptcpub; { Assembler OPTimizer CPU specific Base }
|
||||
Interface
|
||||
|
||||
Uses
|
||||
aasmcpu,AOptBase;
|
||||
aasmcpu,AOptBase, cpubase;
|
||||
|
||||
Type
|
||||
|
||||
@ -62,7 +64,7 @@ Type
|
||||
{ **************************** TAoptBaseCpu ******************************* }
|
||||
{ ************************************************************************* }
|
||||
|
||||
TAoptBaseCpu = Object(TAoptBase)
|
||||
TAoptBaseCpu = class(TAoptBase)
|
||||
End;
|
||||
|
||||
|
||||
@ -78,17 +80,17 @@ Const
|
||||
|
||||
{ the maximum number of operands an instruction has }
|
||||
|
||||
MaxOps = 3;
|
||||
MaxOps = 5;
|
||||
|
||||
{Oper index of operand that contains the source (reference) with a load }
|
||||
{instruction }
|
||||
|
||||
LoadSrc = 0;
|
||||
LoadSrc = 1;
|
||||
|
||||
{Oper index of operand that contains the destination (register) with a load }
|
||||
{instruction }
|
||||
|
||||
LoadDst = 1;
|
||||
LoadDst = 0;
|
||||
|
||||
{Oper index of operand that contains the source (register) with a store }
|
||||
{instruction }
|
||||
@ -100,6 +102,10 @@ Const
|
||||
|
||||
StoreDst = 1;
|
||||
|
||||
|
||||
aopt_uncondjmp = A_B;
|
||||
aopt_condjmp = A_BC;
|
||||
|
||||
Implementation
|
||||
|
||||
{ ************************************************************************* }
|
||||
@ -117,7 +123,15 @@ End.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.7 2005-02-14 17:13:10 peter
|
||||
Revision 1.8 2005-02-26 01:27:00 jonas
|
||||
* fixed generic jumps optimizer and enabled it for ppc (the label table
|
||||
was not being initialised -> getfinaldestination always failed, which
|
||||
caused wrong optimizations in some cases)
|
||||
* changed the inverse_cond into a function, because tasmcond is a record
|
||||
on ppc
|
||||
+ added a compare_conditions() function for the same reason
|
||||
|
||||
Revision 1.7 2005/02/14 17:13:10 peter
|
||||
* truncate log
|
||||
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ unit aoptcpuc;
|
||||
|
||||
Interface
|
||||
|
||||
{$i fpcdefs.inc}
|
||||
|
||||
Uses
|
||||
AOptCs;
|
||||
|
||||
@ -39,7 +41,15 @@ Implementation
|
||||
End.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.6 2005-02-14 17:13:10 peter
|
||||
Revision 1.7 2005-02-26 01:27:00 jonas
|
||||
* fixed generic jumps optimizer and enabled it for ppc (the label table
|
||||
was not being initialised -> getfinaldestination always failed, which
|
||||
caused wrong optimizations in some cases)
|
||||
* changed the inverse_cond into a function, because tasmcond is a record
|
||||
on ppc
|
||||
+ added a compare_conditions() function for the same reason
|
||||
|
||||
Revision 1.6 2005/02/14 17:13:10 peter
|
||||
* truncate log
|
||||
|
||||
}
|
||||
|
@ -24,14 +24,15 @@
|
||||
}
|
||||
Unit aoptcpud;
|
||||
|
||||
{$i fpcdefs.inc}
|
||||
|
||||
Interface
|
||||
|
||||
uses
|
||||
AOptDA;
|
||||
|
||||
Type
|
||||
PAOptDFACpu = ^TAOptDFACpu;
|
||||
TAOptDFACpu = Object(TAOptDFA)
|
||||
TAOptDFACpu = class(TAOptDFA)
|
||||
End;
|
||||
|
||||
Implementation
|
||||
@ -41,7 +42,15 @@ End.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.6 2005-02-14 17:13:10 peter
|
||||
Revision 1.7 2005-02-26 01:27:00 jonas
|
||||
* fixed generic jumps optimizer and enabled it for ppc (the label table
|
||||
was not being initialised -> getfinaldestination always failed, which
|
||||
caused wrong optimizations in some cases)
|
||||
* changed the inverse_cond into a function, because tasmcond is a record
|
||||
on ppc
|
||||
+ added a compare_conditions() function for the same reason
|
||||
|
||||
Revision 1.6 2005/02/14 17:13:10 peter
|
||||
* truncate log
|
||||
|
||||
}
|
||||
|
@ -384,7 +384,6 @@ uses
|
||||
function is_calljmp(o:tasmop):boolean;
|
||||
|
||||
procedure inverse_flags(var r : TResFlags);
|
||||
procedure inverse_cond(const c: TAsmCond;var r : TAsmCond);
|
||||
function flags_to_cond(const f: TResFlags) : TAsmCond;
|
||||
procedure create_cond_imm(BO,BI:byte;var r : TAsmCond);
|
||||
procedure create_cond_norm(cond: TAsmCondFlag; cr: byte;var r : TasmCond);
|
||||
@ -398,6 +397,8 @@ uses
|
||||
function std_regname(r:Tregister):string;
|
||||
function is_condreg(r : tregister):boolean;
|
||||
|
||||
function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
function conditions_equal(const c1, c2: TAsmCond): boolean;
|
||||
|
||||
implementation
|
||||
|
||||
@ -441,14 +442,27 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure inverse_cond(const c: TAsmCond;var r : TAsmCond);
|
||||
function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
const
|
||||
inv_condflags:array[TAsmCondFlag] of TAsmCondFlag=(C_None,
|
||||
C_GE,C_GT,C_NE,C_LT,C_LE,C_LT,C_EQ,C_GT,C_NS,C_SO,C_NU,C_UN,
|
||||
C_F,C_T,C_DNZ,C_DNZF,C_DNZT,C_DZ,C_DZF,C_DZT);
|
||||
begin
|
||||
r := c;
|
||||
r.cond := inv_condflags[c.cond];
|
||||
if (c.cond in [C_DNZ,C_DZ]) then
|
||||
internalerror(2005022501);
|
||||
result := c;
|
||||
result.cond := inv_condflags[c.cond];
|
||||
end;
|
||||
|
||||
|
||||
function conditions_equal(const c1, c2: TAsmCond): boolean;
|
||||
begin
|
||||
result :=
|
||||
(c1.simple and c2.simple) and
|
||||
(c1.cond = c2.cond) and
|
||||
((not(c1.cond in [C_T..C_DZF]) and
|
||||
(c1.cr = c2.cr)) or
|
||||
(c1.crbit = c2.crbit));
|
||||
end;
|
||||
|
||||
|
||||
@ -544,7 +558,15 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.97 2005-02-18 23:05:47 jonas
|
||||
Revision 1.98 2005-02-26 01:27:00 jonas
|
||||
* fixed generic jumps optimizer and enabled it for ppc (the label table
|
||||
was not being initialised -> getfinaldestination always failed, which
|
||||
caused wrong optimizations in some cases)
|
||||
* changed the inverse_cond into a function, because tasmcond is a record
|
||||
on ppc
|
||||
+ added a compare_conditions() function for the same reason
|
||||
|
||||
Revision 1.97 2005/02/18 23:05:47 jonas
|
||||
- removed a non-existing instruction (lcrxe)
|
||||
* fixed an instruction (maffs_ -> mffs)
|
||||
|
||||
|
@ -59,12 +59,29 @@ implementation
|
||||
{$ifndef NOAGPPPCMPW}
|
||||
,agppcmpw
|
||||
{$endif}
|
||||
|
||||
|
||||
{**************************************
|
||||
Optimizer
|
||||
**************************************}
|
||||
|
||||
{$ifndef NOOPT}
|
||||
, aoptcpu
|
||||
{$endif NOOPT}
|
||||
;
|
||||
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.9 2005-02-14 17:13:10 peter
|
||||
Revision 1.10 2005-02-26 01:27:00 jonas
|
||||
* fixed generic jumps optimizer and enabled it for ppc (the label table
|
||||
was not being initialised -> getfinaldestination always failed, which
|
||||
caused wrong optimizations in some cases)
|
||||
* changed the inverse_cond into a function, because tasmcond is a record
|
||||
on ppc
|
||||
+ added a compare_conditions() function for the same reason
|
||||
|
||||
Revision 1.9 2005/02/14 17:13:10 peter
|
||||
* truncate log
|
||||
|
||||
}
|
||||
|
@ -112,13 +112,6 @@ uses
|
||||
'e','g','l','ge','le','ne'
|
||||
);
|
||||
|
||||
inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
|
||||
C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
|
||||
C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
|
||||
C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ,
|
||||
C_FNE,C_FLE,C_FGE,C_FL,C_FG,C_FE
|
||||
);
|
||||
|
||||
const
|
||||
CondAsmOps=2;
|
||||
CondAsmOp:array[0..CondAsmOps-1] of TAsmOp=(
|
||||
@ -336,6 +329,9 @@ uses
|
||||
function is_calljmp(o:tasmop):boolean;
|
||||
|
||||
procedure inverse_flags(var f: TResFlags);
|
||||
function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
|
||||
function flags_to_cond(const f: TResFlags) : TAsmCond;
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
function reg_cgsize(const reg: tregister): tcgsize;
|
||||
@ -446,10 +442,35 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
const
|
||||
inverse: array[TAsmCond] of TAsmCond=(C_None,
|
||||
C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
|
||||
C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
|
||||
C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ,
|
||||
C_FNE,C_FLE,C_FGE,C_FL,C_FG,C_FE
|
||||
);
|
||||
begin
|
||||
result := inverse[c];
|
||||
end;
|
||||
|
||||
function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
begin
|
||||
result := c1 = c2;
|
||||
end;
|
||||
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.77 2005-02-14 17:13:10 peter
|
||||
Revision 1.78 2005-02-26 01:27:00 jonas
|
||||
* fixed generic jumps optimizer and enabled it for ppc (the label table
|
||||
was not being initialised -> getfinaldestination always failed, which
|
||||
caused wrong optimizations in some cases)
|
||||
* changed the inverse_cond into a function, because tasmcond is a record
|
||||
on ppc
|
||||
+ added a compare_conditions() function for the same reason
|
||||
|
||||
Revision 1.77 2005/02/14 17:13:10 peter
|
||||
* truncate log
|
||||
|
||||
Revision 1.76 2005/01/20 16:38:45 peter
|
||||
|
@ -209,12 +209,6 @@ uses
|
||||
'ns','nz','o','p','pe','po','s','z'
|
||||
);
|
||||
|
||||
inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
|
||||
C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
|
||||
C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
|
||||
C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
|
||||
);
|
||||
|
||||
{*****************************************************************************
|
||||
Flags
|
||||
*****************************************************************************}
|
||||
@ -258,6 +252,8 @@ uses
|
||||
function std_regnum_search(const s:string):Tregister;
|
||||
function std_regname(r:Tregister):string;
|
||||
|
||||
function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
|
||||
implementation
|
||||
|
||||
@ -445,10 +441,38 @@ implementation
|
||||
result:=generic_regname(r);
|
||||
end;
|
||||
|
||||
|
||||
function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
const
|
||||
inverse: array[TAsmCond] of TAsmCond=(C_None,
|
||||
C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
|
||||
C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
|
||||
C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
|
||||
);
|
||||
begin
|
||||
result := inverse[c];
|
||||
end;
|
||||
|
||||
|
||||
function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
begin
|
||||
result := c1 = c2;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.50 2005-02-14 17:13:10 peter
|
||||
Revision 1.51 2005-02-26 01:27:00 jonas
|
||||
* fixed generic jumps optimizer and enabled it for ppc (the label table
|
||||
was not being initialised -> getfinaldestination always failed, which
|
||||
caused wrong optimizations in some cases)
|
||||
* changed the inverse_cond into a function, because tasmcond is a record
|
||||
on ppc
|
||||
+ added a compare_conditions() function for the same reason
|
||||
|
||||
Revision 1.50 2005/02/14 17:13:10 peter
|
||||
* truncate log
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user