Prechádzať zdrojové kódy

* 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

Jonas Maebe 20 rokov pred
rodič
commit
ec959955bd

+ 62 - 35
compiler/aopt.pas

@@ -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);
-        LabelInfo^.LowLabel := High(AWord);
-        LabelInfo^.HighLabel := 0;
-        LabelInfo^.LabelDif := 0;
-        LabelInfo^.LabelTable:=nil;
       End;
 
-    Function TAsmOptimizer.FindLoHiLabels: tai;
+    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: tai;
+          p, prev: tai;
       Begin
+        LabelInfo^.LowLabel := High(AWord);
+        LabelInfo^.HighLabel := 0;
+        LabelInfo^.LabelDif := 0;
+        LabelInfo^.LabelTable:=nil;
         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
 
 }

+ 16 - 6
compiler/aoptobj.pas

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

+ 10 - 2
compiler/arm/cgcpu.pas

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

+ 30 - 6
compiler/arm/cpubase.pas

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

+ 9 - 3
compiler/fpcdefs.inc

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

+ 15 - 7
compiler/i386/popt386.pas

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

+ 15 - 3
compiler/powerpc/aoptcpu.pas

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

+ 20 - 6
compiler/powerpc/aoptcpub.pas

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

+ 11 - 1
compiler/powerpc/aoptcpuc.pas

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

+ 12 - 3
compiler/powerpc/aoptcpud.pas

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

+ 27 - 5
compiler/powerpc/cpubase.pas

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

+ 18 - 1
compiler/powerpc/cputarg.pas

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

+ 29 - 8
compiler/sparc/cpubase.pas

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

+ 31 - 7
compiler/x86/cpubase.pas

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