Browse Source

* "add/sub const,%esp;sub $2,%esp" wasn't always optimized

Jonas Maebe 26 years ago
parent
commit
aff06b2d4e
1 changed files with 106 additions and 61 deletions
  1. 106 61
      compiler/popt386.pas

+ 106 - 61
compiler/popt386.pas

@@ -47,7 +47,7 @@ Procedure PeepHoleOptPass1(Asml: PAasmOutput; BlockStart, BlockEnd: Pai);
 
 
 Var
 Var
   l : longint;
   l : longint;
-  p ,hp1, hp2: pai;
+  p ,hp1, hp2, hp3, hp4: pai;
   TmpBool1, TmpBool2: Boolean;
   TmpBool1, TmpBool2: Boolean;
 
 
   TmpRef: PReference;
   TmpRef: PReference;
@@ -97,6 +97,51 @@ Var
       End;
       End;
   End;
   End;
 
 
+  Function DoSubAddOpt(var p: Pai): Boolean;
+  Begin
+    DoSubAddOpt := False;
+    If GetLastInstruction(p, hp1) And
+       (hp1^.typ = ait_instruction) And
+       (Pai386(hp1)^.opsize = Pai386(p)^.opsize) then
+      Case Pai386(hp1)^.opcode Of
+        A_DEC:
+          If (Pai386(hp1)^.oper[0].typ = top_reg) And
+             (Pai386(hp1)^.oper[0].reg = Pai386(p)^.oper[1].reg) Then
+            Begin
+              Pai386(p)^.LoadConst(0,Pai386(p)^.oper[0].val+1);
+              AsmL^.Remove(hp1);
+              Dispose(hp1, Done)
+            End;
+         A_SUB:
+           If (Pai386(hp1)^.oper[0].typ = top_const) And
+              (Pai386(hp1)^.oper[1].typ = top_reg) And
+              (Pai386(hp1)^.oper[1].reg = Pai386(p)^.oper[1].reg) Then
+             Begin
+               Pai386(p)^.LoadConst(0,Pai386(p)^.oper[0].val+Pai386(hp1)^.oper[0].val);
+               AsmL^.Remove(hp1);
+               Dispose(hp1, Done)
+             End;
+         A_ADD:
+           If (Pai386(hp1)^.oper[0].typ = top_const) And
+              (Pai386(hp1)^.oper[1].typ = top_reg) And
+              (Pai386(hp1)^.oper[1].reg = Pai386(p)^.oper[1].reg) Then
+             Begin
+               Pai386(p)^.LoadConst(0,Pai386(p)^.oper[0].val-Pai386(hp1)^.oper[0].val);
+               AsmL^.Remove(hp1);
+               Dispose(hp1, Done);
+               If (Pai386(p)^.oper[0].val = 0) Then
+                 Begin
+                   hp1 := Pai(p^.next);
+                   AsmL^.Remove(p);
+                   Dispose(p, Done);
+                   If Not GetLastInstruction(hp1, p) Then
+                     p := hp1;
+                   DoSubAddOpt := True;
+                 End
+             End;
+       End;
+  End;
+
 Begin
 Begin
   P := BlockStart;
   P := BlockStart;
   UsedRegs := [];
   UsedRegs := [];
@@ -113,7 +158,6 @@ Begin
       because it can never be executed}
       because it can never be executed}
                If (pai386(p)^.opcode = A_JMP) Then
                If (pai386(p)^.opcode = A_JMP) Then
                  Begin
                  Begin
-                   hp1 := pai(p^.next);
                    While GetNextInstruction(p, hp1) and
                    While GetNextInstruction(p, hp1) and
                          ((hp1^.typ <> ait_label) or
                          ((hp1^.typ <> ait_label) or
                    { skip unused labels, they're not referenced anywhere }
                    { skip unused labels, they're not referenced anywhere }
@@ -210,13 +254,50 @@ Begin
               A_CMP:
               A_CMP:
                 Begin
                 Begin
                   If (Pai386(p)^.oper[0].typ = top_const) And
                   If (Pai386(p)^.oper[0].typ = top_const) And
-                     (Pai386(p)^.oper[1].typ = top_reg) And
+                     (Pai386(p)^.oper[1].typ in [top_reg,top_ref]) And
                      (Pai386(p)^.oper[0].val = 0) Then
                      (Pai386(p)^.oper[0].val = 0) Then
+{$ifdef foropt}
+                    If GetNextInstruction(p, hp1) And
+                       (hp1^.typ = ait_instruction) And
+                       (Pai386(hp1)^.is_jmp) and
+                       (pai386(hp1)^.opcode=A_Jcc) and
+                       (pai386(hp1)^.condition in [C_LE,C_BE]) and
+                       GetNextInstruction(hp1,hp2) and
+                       (hp2^.typ = ait_instruction) and
+                       (Pai386(hp2)^.opcode = A_DEC) And
+                       OpsEqual(Pai386(hp2)^.oper[0],Pai386(p)^.oper[1]) And
+                       GetNextInstruction(hp2, hp3) And
+                       (hp3^.typ = ait_instruction) and
+                       (Pai386(hp3)^.is_jmp) and
+                       (Pai386(hp3)^.opcode = A_JMP) And
+                       GetNextInstruction(hp3, hp4) And
+                       FindLabel(PAsmLabel(pai386(hp1)^.oper[0].sym),hp4)
+                      Then
+                        Begin
+                          Pai386(hp2)^.Opcode := A_SUB;
+                          Pai386(hp2)^.Loadoper(1,Pai386(hp2)^.oper[0]);
+                          Pai386(hp2)^.LoadConst(0,1);
+                          Pai386(hp2)^.ops:=2;
+                          Pai386(hp3)^.Opcode := A_Jcc;
+                          Case pai386(hp1)^.condition of
+                            C_LE: Pai386(hp3)^.condition := C_GE;
+                            C_BE: Pai386(hp3)^.condition := C_AE;
+                          End;
+                          AsmL^.Remove(p);
+                          AsmL^.Remove(hp1);
+                          Dispose(p, Done);
+                          Dispose(hp1, Done);
+                          p := hp2;
+                          continue;
+                        End
+                      Else
+{$endif foropt}
                  {change "cmp $0, %reg" to "test %reg, %reg"}
                  {change "cmp $0, %reg" to "test %reg, %reg"}
-                    Begin
-                      Pai386(p)^.opcode := A_TEST;
-                      Pai386(p)^.loadreg(0,Pai386(p)^.oper[1].reg);
-                    End;
+                  If (Pai386(p)^.oper[1].typ = top_reg) Then
+                      Begin
+                        Pai386(p)^.opcode := A_TEST;
+                        Pai386(p)^.loadreg(0,Pai386(p)^.oper[1].reg);
+                      End;
                 End;
                 End;
               A_FLD:
               A_FLD:
                 Begin
                 Begin
@@ -362,7 +443,8 @@ Begin
                      (Not(GetNextInstruction(p, hp1)) Or
                      (Not(GetNextInstruction(p, hp1)) Or
                        {GetNextInstruction(p, hp1) And}
                        {GetNextInstruction(p, hp1) And}
                        Not((Pai(hp1)^.typ = ait_instruction) And
                        Not((Pai(hp1)^.typ = ait_instruction) And
-                           ((pai386(hp1)^.opcode=A_Jcc) and (pai386(hp1)^.condition in [C_O,C_NO]))))
+                           ((pai386(hp1)^.opcode=A_Jcc) and
+                            (pai386(hp1)^.condition in [C_O,C_NO]))))
                     Then
                     Then
                       Begin
                       Begin
                         New(TmpRef);
                         New(TmpRef);
@@ -1284,9 +1366,9 @@ Begin
                                      (Pai386(hp1)^.oper[1].ref^.base = R_ESP)))) do
                                      (Pai386(hp1)^.oper[1].ref^.base = R_ESP)))) do
                           hp1 := Pai(hp1^.next);
                           hp1 := Pai(hp1^.next);
                         If Assigned(hp1) And
                         If Assigned(hp1) And
-                            (Pai(hp1)^.typ = ait_instruction) And
-                            (Pai386(hp1)^.opcode = A_PUSH) And
-                            (Pai386(hp1)^.opsize = S_W)
+                           (Pai(hp1)^.typ = ait_instruction) And
+                           (Pai386(hp1)^.opcode = A_PUSH) And
+                           (Pai386(hp1)^.opsize = S_W)
                           Then
                           Then
                             Begin
                             Begin
                               Pai386(hp1)^.changeopsize(S_L);
                               Pai386(hp1)^.changeopsize(S_L);
@@ -1297,53 +1379,10 @@ Begin
                               Dispose(p, Done);
                               Dispose(p, Done);
                               p := hp1;
                               p := hp1;
                               Continue
                               Continue
-                            End
-                          Else
-                            If GetLastInstruction(p, hp1) And
-                               (Pai(hp1)^.typ = ait_instruction) And
-                               (Pai386(hp1)^.opcode = A_SUB) And
-                               (Pai386(hp1)^.oper[0].typ = top_const) And
-                               (Pai386(hp1)^.oper[1].typ = top_reg) And
-                               (Pai386(hp1)^.oper[1].reg = R_ESP)
-                              Then
-                                Begin
-                                  Pai386(p)^.LoadConst(0,Pai386(p)^.oper[0].val+Pai386(hp1)^.oper[0].val);
-                                  AsmL^.Remove(hp1);
-                                  Dispose(hp1, Done);
-                                End;
+                            End;
+                        If DoSubAddOpt(p) Then continue;
                       End
                       End
-                    Else
-                      If GetLastInstruction(p, hp1) And
-                         (hp1^.typ = ait_instruction) And
-                         (Pai386(hp1)^.opsize = Pai386(p)^.opsize) then
-                        Case Pai386(hp1)^.opcode Of
-                          A_DEC:
-                            If (Pai386(hp1)^.oper[0].typ = top_reg) And
-                               (Pai386(hp1)^.oper[0].reg = Pai386(p)^.oper[1].reg) Then
-                              Begin
-                                Pai386(p)^.LoadConst(0,Pai386(p)^.oper[0].val+1);
-                                AsmL^.Remove(hp1);
-                                Dispose(hp1, Done)
-                              End;
-                          A_SUB:
-                            If (Pai386(hp1)^.oper[0].typ = top_const) And
-                               (Pai386(hp1)^.oper[1].typ = top_reg) And
-                               (Pai386(hp1)^.oper[1].reg = Pai386(p)^.oper[1].reg) Then
-                              Begin
-                                Pai386(p)^.LoadConst(0,Pai386(p)^.oper[0].val+Pai386(hp1)^.oper[0].val);
-                                AsmL^.Remove(hp1);
-                                Dispose(hp1, Done)
-                              End;
-                          A_ADD:
-                            If (Pai386(hp1)^.oper[0].typ = top_const) And
-                               (Pai386(hp1)^.oper[1].typ = top_reg) And
-                               (Pai386(hp1)^.oper[1].reg = Pai386(p)^.oper[1].reg) Then
-                              Begin
-                                Pai386(p)^.LoadConst(0,Pai386(p)^.oper[0].val-Pai386(hp1)^.oper[0].val);
-                                AsmL^.Remove(hp1);
-                                Dispose(hp1, Done)
-                              End;
-                        End
+                    Else If DoSubAddOpt(p) Then Continue
                 End;
                 End;
               A_TEST, A_OR:
               A_TEST, A_OR:
                 {removes the line marked with (x) from the sequence
                 {removes the line marked with (x) from the sequence
@@ -1352,8 +1391,8 @@ Begin
                  j(n)z _Label
                  j(n)z _Label
                     as the first instruction already adjusts the ZF}
                     as the first instruction already adjusts the ZF}
                  Begin
                  Begin
-                   If OpsEqual(Pai386(p)^.oper[0],Pai386(p)^.oper[1]) And
-                      GetLastInstruction(p, hp1) And
+                   If OpsEqual(Pai386(p)^.oper[0],Pai386(p)^.oper[1]) Then
+                    If GetLastInstruction(p, hp1) And
                       (pai(hp1)^.typ = ait_instruction) Then
                       (pai(hp1)^.typ = ait_instruction) Then
                      Case Pai386(hp1)^.opcode Of
                      Case Pai386(hp1)^.opcode Of
                        A_ADD, A_SUB, A_OR, A_XOR, A_AND, A_SHL, A_SHR:
                        A_ADD, A_SUB, A_OR, A_XOR, A_AND, A_SHL, A_SHR:
@@ -1391,7 +1430,10 @@ Begin
                                continue
                                continue
                              End;
                              End;
                          End
                          End
-                     End;
+                     End
+                    Else
+
+
                  End;
                  End;
             End;
             End;
             end; { if is_jmp }
             end; { if is_jmp }
@@ -1524,7 +1566,10 @@ End.
 
 
 {
 {
  $Log$
  $Log$
- Revision 1.60  1999-08-04 00:23:16  florian
+ Revision 1.61  1999-08-05 15:02:48  jonas
+   * "add/sub const,%esp;sub $2,%esp" wasn't always optimized
+
+ Revision 1.60  1999/08/04 00:23:16  florian
    * renamed i386asm and i386base to cpuasm and cpubase
    * renamed i386asm and i386base to cpuasm and cpubase
 
 
  Revision 1.59  1999/08/03 17:13:28  jonas
  Revision 1.59  1999/08/03 17:13:28  jonas