Explorar o código

* internal changeregsize for optimizer
* fix with a hack to not remove the first instruction of a block
which will leave blockstart pointing to invalid memory

peter %!s(int64=22) %!d(string=hai) anos
pai
achega
4c66ac6cab
Modificáronse 4 ficheiros con 133 adicións e 51 borrados
  1. 12 7
      compiler/i386/csopt386.pas
  2. 86 21
      compiler/i386/daopt386.pas
  3. 20 13
      compiler/i386/popt386.pas
  4. 15 10
      compiler/i386/rropt386.pas

+ 12 - 7
compiler/i386/csopt386.pas

@@ -832,11 +832,11 @@ begin
   if reg.enum = newReg.enum then
     reg := orgReg
   else if (reg.enum in regset8bit) and
-          (reg.enum = rg.makeregsize(newReg,OS_8).enum) then
-    reg := rg.makeregsize(orgReg,OS_8)
+          (reg.enum = changeregsize(newReg,S_B).enum) then
+    reg := changeregsize(orgReg,S_B)
   else if (reg.enum in regset16bit) and
-          (reg.enum = rg.makeregsize(newReg,OS_16).enum) then
-    reg := rg.makeregsize(orgReg,OS_16)
+          (reg.enum = changeregsize(newReg,S_W).enum) then
+    reg := changeregsize(orgReg,S_W)
   else
     changeReg := false;
 end;
@@ -1396,9 +1396,9 @@ begin
             begin
               case t.opsize of
                 S_B,S_BW,S_BL:
-                  memtoreg := rg.makeregsize(regcounter,OS_8);
+                  memtoreg := changeregsize(regcounter,S_B);
                 S_W,S_WL:
-                  memtoreg := rg.makeregsize(regcounter,OS_16);
+                  memtoreg := changeregsize(regcounter,S_W);
                 S_L:
                   memtoreg := regcounter;
               end;
@@ -1997,7 +1997,12 @@ End.
 
 {
   $Log$
-  Revision 1.46  2003-05-30 23:57:08  peter
+  Revision 1.47  2003-06-03 21:09:05  peter
+    * internal changeregsize for optimizer
+    * fix with a hack to not remove the first instruction of a block
+      which will leave blockstart pointing to invalid memory
+
+  Revision 1.46  2003/05/30 23:57:08  peter
     * more sparc cleanup
     * accumulator removed, splitted in function_return_reg (called) and
       function_result_reg (caller)

+ 86 - 21
compiler/i386/daopt386.pas

@@ -158,6 +158,8 @@ type
 
 Procedure InsertLLItem(AsmL: TAAsmOutput; prev, foll, new_one: TLinkedListItem);
 
+
+function changeregsize(r:tregister;size:topsize):tregister;
 Function Reg32(Reg: TRegister): TRegister;
 Function RefsEquivalent(Const R1, R2: TReference; Var RegInfo: TRegInfo; OpAct: TOpAction): Boolean;
 Function RefsEqual(Const R1, R2: TReference): Boolean;
@@ -573,6 +575,64 @@ End;
 
 {************************ Some general functions ************************}
 
+  const
+    reg2reg32 : array[firstreg..lastreg] of Toldregister = (R_NO,
+      R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
+      R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
+      R_EAX,R_ECX,R_EDX,R_EBX,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO
+    );
+    reg2reg16 : array[firstreg..lastreg] of Toldregister = (R_NO,
+      R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
+      R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
+      R_AX,R_CX,R_DX,R_BX,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO
+    );
+    reg2reg8 : array[firstreg..lastreg] of Toldregister = (R_NO,
+      R_AL,R_CL,R_DL,R_BL,R_NO,R_NO,R_NO,R_NO,
+      R_AL,R_CL,R_DL,R_BL,R_NO,R_NO,R_NO,R_NO,
+      R_AL,R_CL,R_DL,R_BL,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,
+      R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO,R_NO
+    );
+
+    { convert a register to a specfied register size }
+    function changeregsize(r:tregister;size:topsize):tregister;
+      var
+        reg : tregister;
+      begin
+        case size of
+          S_B :
+            reg.enum:=reg2reg8[r.enum];
+          S_W :
+            reg.enum:=reg2reg16[r.enum];
+          S_L :
+            reg.enum:=reg2reg32[r.enum];
+          else
+            internalerror(200204101);
+        end;
+        if reg.enum=R_NO then
+         internalerror(200204102);
+        changeregsize:=reg;
+      end;
+
 Function TCh2Reg(Ch: TInsChange): ToldRegister;
 {converts a TChange variable to a TRegister}
 Begin
@@ -599,10 +659,10 @@ Begin
   If (Reg.enum >= R_AX)
     Then
       If (Reg.enum <= R_DI)
-        Then Reg32 := rg.makeregsize(Reg,OS_INT)
+        Then Reg32 := changeregsize(Reg,S_L)
         Else
           If (Reg.enum <= R_BL)
-            Then Reg32 := rg.makeregsize(Reg,OS_INT);
+            Then Reg32 := changeregsize(Reg,S_L);
 End;
 
 { inserts new_one between prev and foll }
@@ -665,37 +725,37 @@ Begin
       Case OldReg.enum Of
         R_EAX..R_EDI:
           Begin
-            NewRegsEncountered := NewRegsEncountered + [rg.makeregsize(NewReg,OS_16).enum];
-            OldRegsEncountered := OldRegsEncountered + [rg.makeregsize(OldReg,OS_16).enum];
-            New2OldReg[rg.makeregsize(NewReg,OS_16).enum] := rg.makeregsize(OldReg,OS_16);
+            NewRegsEncountered := NewRegsEncountered + [changeregsize(NewReg,S_W).enum];
+            OldRegsEncountered := OldRegsEncountered + [changeregsize(OldReg,S_W).enum];
+            New2OldReg[changeregsize(NewReg,S_W).enum] := changeregsize(OldReg,S_W);
             If (NewReg.enum in [R_EAX..R_EBX]) And
                (OldReg.enum in [R_EAX..R_EBX]) Then
               Begin
-                NewRegsEncountered := NewRegsEncountered + [rg.makeregsize(NewReg,OS_8).enum];
-                OldRegsEncountered := OldRegsEncountered + [rg.makeregsize(OldReg,OS_8).enum];
-                New2OldReg[rg.makeregsize(NewReg,OS_8).enum] := rg.makeregsize(OldReg,OS_8);
+                NewRegsEncountered := NewRegsEncountered + [changeregsize(NewReg,S_B).enum];
+                OldRegsEncountered := OldRegsEncountered + [changeregsize(OldReg,S_B).enum];
+                New2OldReg[changeregsize(NewReg,S_B).enum] := changeregsize(OldReg,S_B);
               End;
           End;
         R_AX..R_DI:
           Begin
-            NewRegsEncountered := NewRegsEncountered + [rg.makeregsize(NewReg,OS_32).enum];
-            OldRegsEncountered := OldRegsEncountered + [rg.makeregsize(OldReg,OS_32).enum];
-            New2OldReg[rg.makeregsize(NewReg,OS_32).enum] := rg.makeregsize(OldReg,OS_32);
+            NewRegsEncountered := NewRegsEncountered + [changeregsize(NewReg,S_L).enum];
+            OldRegsEncountered := OldRegsEncountered + [changeregsize(OldReg,S_L).enum];
+            New2OldReg[changeregsize(NewReg,S_L).enum] := changeregsize(OldReg,S_L);
             If (NewReg.enum in [R_AX..R_BX]) And
                (OldReg.enum in [R_AX..R_BX]) Then
               Begin
-                NewRegsEncountered := NewRegsEncountered + [rg.makeregsize(NewReg,OS_8).enum];
-                OldRegsEncountered := OldRegsEncountered + [rg.makeregsize(OldReg,OS_8).enum];
-                New2OldReg[rg.makeregsize(NewReg,OS_8).enum] := rg.makeregsize(OldReg,OS_8);
+                NewRegsEncountered := NewRegsEncountered + [changeregsize(NewReg,S_B).enum];
+                OldRegsEncountered := OldRegsEncountered + [changeregsize(OldReg,S_B).enum];
+                New2OldReg[changeregsize(NewReg,S_B).enum] := changeregsize(OldReg,S_B);
               End;
           End;
         R_AL..R_BL:
           Begin
-            NewRegsEncountered := NewRegsEncountered + [rg.makeregsize(NewReg,OS_32).enum]
-                               + [rg.makeregsize(NewReg,OS_16).enum];
-            OldRegsEncountered := OldRegsEncountered + [rg.makeregsize(OldReg,OS_32).enum]
-                               + [rg.makeregsize(OldReg,OS_8).enum];
-            New2OldReg[rg.makeregsize(NewReg,OS_32).enum] := rg.makeregsize(OldReg,OS_32);
+            NewRegsEncountered := NewRegsEncountered + [changeregsize(NewReg,S_L).enum]
+                               + [changeregsize(NewReg,S_W).enum];
+            OldRegsEncountered := OldRegsEncountered + [changeregsize(OldReg,S_L).enum]
+                               + [changeregsize(OldReg,S_B).enum];
+            New2OldReg[changeregsize(NewReg,S_L).enum] := changeregsize(OldReg,S_L);
           End;
       End;
     End;
@@ -2669,7 +2729,12 @@ End.
 
 {
   $Log$
-  Revision 1.50  2003-05-26 21:17:18  peter
+  Revision 1.51  2003-06-03 21:09:05  peter
+    * internal changeregsize for optimizer
+    * fix with a hack to not remove the first instruction of a block
+      which will leave blockstart pointing to invalid memory
+
+  Revision 1.50  2003/05/26 21:17:18  peter
     * procinlinenode removed
     * aktexit2label removed, fast exit removed
     + tcallnode.inlined_pass_2 added
@@ -2749,7 +2814,7 @@ End.
       the parast, detected by tcalcst3 test
 
   Revision 1.33  2002/04/21 15:32:59  carl
-  * changeregsize -> rg.makeregsize
+  * changeregsize -> changeregsize
 
   Revision 1.32  2002/04/20 21:37:07  carl
   + generic FPC_CHECKPOINTER

+ 20 - 13
compiler/i386/popt386.pas

@@ -611,7 +611,9 @@ Begin
                { remove jumps to a label coming right after them }
                If GetNextInstruction(p, hp1) then
                  Begin
-                   if FindLabel(tasmlabel(Taicpu(p).oper[0].sym), hp1) then
+                   if FindLabel(tasmlabel(Taicpu(p).oper[0].sym), hp1) and
+{$warning FIXME removing the first instruction fails}
+                      (p<>blockstart) then
                      Begin
                        hp2:=Tai(hp1.next);
                        asml.remove(p);
@@ -1226,7 +1228,7 @@ Begin
                       Case Taicpu(p).opsize of
                         S_BW:
                           Begin
-                            If (rg.makeregsize(Taicpu(p).oper[0].reg,OS_16).enum=Taicpu(p).oper[1].reg.enum) And
+                            If (changeregsize(Taicpu(p).oper[0].reg,S_W).enum=Taicpu(p).oper[1].reg.enum) And
                                Not(CS_LittleSize In aktglobalswitches)
                               Then
                                 {Change "movzbw %al, %ax" to "andw $0x0ffh, %ax"}
@@ -1248,13 +1250,13 @@ Begin
                                     Begin
                                       Taicpu(p).opcode := A_MOV;
                                       Taicpu(p).changeopsize(S_W);
-                                      Taicpu(p).LoadReg(0,rg.makeregsize(Taicpu(p).oper[0].reg,OS_16));
+                                      Taicpu(p).LoadReg(0,changeregsize(Taicpu(p).oper[0].reg,S_W));
                                       Taicpu(hp1).LoadConst(0,Taicpu(hp1).oper[0].val And $ff);
                                     End;
                           End;
                         S_BL:
                           Begin
-                            If (rg.makeregsize(Taicpu(p).oper[0].reg,OS_32).enum=Taicpu(p).oper[1].reg.enum) And
+                            If (changeregsize(Taicpu(p).oper[0].reg,S_L).enum=Taicpu(p).oper[1].reg.enum) And
                                Not(CS_LittleSize in aktglobalswitches)
                               Then
                                 {Change "movzbl %al, %eax" to "andl $0x0ffh, %eax"}
@@ -1276,13 +1278,13 @@ Begin
                                     Begin
                                       Taicpu(p).opcode := A_MOV;
                                       Taicpu(p).changeopsize(S_L);
-                                      Taicpu(p).LoadReg(0,rg.makeregsize(Taicpu(p).oper[0].reg,OS_32));
+                                      Taicpu(p).LoadReg(0,changeregsize(Taicpu(p).oper[0].reg,S_L));
                                       Taicpu(hp1).LoadConst(0,Taicpu(hp1).oper[0].val And $ff);
                                     End
                           End;
                         S_WL:
                           Begin
-                            If (rg.makeregsize(Taicpu(p).oper[0].reg,OS_32).enum=Taicpu(p).oper[1].reg.enum) And
+                            If (changeregsize(Taicpu(p).oper[0].reg,S_L).enum=Taicpu(p).oper[1].reg.enum) And
                                Not(CS_LittleSize In aktglobalswitches)
                               Then
                                {Change "movzwl %ax, %eax" to "andl $0x0ffffh, %eax"}
@@ -1304,7 +1306,7 @@ Begin
                                     Begin
                                       Taicpu(p).opcode := A_MOV;
                                       Taicpu(p).changeopsize(S_L);
-                                      Taicpu(p).LoadReg(0,rg.makeregsize(Taicpu(p).oper[0].reg,OS_32));
+                                      Taicpu(p).LoadReg(0,changeregsize(Taicpu(p).oper[0].reg,S_L));
                                       Taicpu(hp1).LoadConst(0,Taicpu(hp1).oper[0].val And $ffff);
                                     End;
                           End;
@@ -1612,7 +1614,7 @@ Begin
                             Begin
                               Taicpu(hp1).changeopsize(S_L);
                               if Taicpu(hp1).oper[0].typ=top_reg then
-                                Taicpu(hp1).LoadReg(0,rg.makeregsize(Taicpu(hp1).oper[0].reg,OS_32));
+                                Taicpu(hp1).LoadReg(0,changeregsize(Taicpu(hp1).oper[0].reg,S_L));
                               hp1 := Tai(p.next);
                               asml.Remove(p);
                               p.free;
@@ -1976,7 +1978,7 @@ See test/tgadint64 in the test suite.
                                     InsertLLItem(AsmL,p.previous, p, hp1);
                                     Taicpu(p).opcode := A_MOV;
                                     Taicpu(p).changeopsize(S_B);
-                                    Taicpu(p).LoadReg(1,rg.makeregsize(Taicpu(p).oper[1].reg,OS_8));
+                                    Taicpu(p).LoadReg(1,changeregsize(Taicpu(p).oper[1].reg,S_B));
                                   End;
                             End;
                         End
@@ -1996,7 +1998,7 @@ See test/tgadint64 in the test suite.
                                          Taicpu(p).oper[1].reg);
                               Taicpu(p).opcode := A_MOV;
                               Taicpu(p).changeopsize(S_B);
-                              Taicpu(p).LoadReg(1,rg.makeregsize(Taicpu(p).oper[1].reg,OS_8));
+                              Taicpu(p).LoadReg(1,changeregsize(Taicpu(p).oper[1].reg,S_B));
                               InsertLLItem(AsmL,p.previous, p, hp1);
                             End;
                  End;
@@ -2061,7 +2063,12 @@ End.
 
 {
   $Log$
-  Revision 1.45  2003-06-02 21:42:05  jonas
+  Revision 1.46  2003-06-03 21:09:05  peter
+    * internal changeregsize for optimizer
+    * fix with a hack to not remove the first instruction of a block
+      which will leave blockstart pointing to invalid memory
+
+  Revision 1.45  2003/06/02 21:42:05  jonas
     * function results can now also be regvars
     - removed tprocinfo.return_offset, never use it again since it's invalid
       if the result is a regvar
@@ -2165,7 +2172,7 @@ End.
       the parast, detected by tcalcst3 test
 
   Revision 1.23  2002/04/21 15:40:49  carl
-  * changeregsize -> rg.makeregsize
+  * changeregsize -> changeregsize
 
   Revision 1.22  2002/04/20 21:37:07  carl
   + generic FPC_CHECKPOINTER
@@ -2180,7 +2187,7 @@ End.
   Revision 1.21  2002/04/15 19:44:21  peter
     * fixed stackcheck that would be called recursively when a stack
       error was found
-    * generic rg.makeregsize(reg,size) for i386 register resizing
+    * generic changeregsize(reg,size) for i386 register resizing
     * removed some more routines from cga unit
     * fixed returnvalue handling
     * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)

+ 15 - 10
compiler/i386/rropt386.pas

@@ -87,17 +87,17 @@ begin
     reg := reg1
   else if (reg.enum in regset8bit) then
     begin
-      if (reg.enum = rg.makeregsize(reg1,OS_8).enum) then
-        reg := rg.makeregsize(reg2,OS_8)
-      else if reg.enum = rg.makeregsize(reg2,OS_8).enum then
-        reg := rg.makeregsize(reg1,OS_8);
+      if (reg.enum = changeregsize(reg1,S_B).enum) then
+        reg := changeregsize(reg2,S_B)
+      else if reg.enum = changeregsize(reg2,S_B).enum then
+        reg := changeregsize(reg1,S_B);
     end
   else if (reg.enum in regset16bit) then
     begin
-      if reg.enum = rg.makeregsize(reg1,OS_16).enum then
-        reg := rg.makeregsize(reg2,OS_16)
-      else if reg.enum = rg.makeregsize(reg2,OS_16).enum then
-        reg := rg.makeregsize(reg1,OS_16);
+      if reg.enum = changeregsize(reg1,S_W).enum then
+        reg := changeregsize(reg2,S_W)
+      else if reg.enum = changeregsize(reg2,S_W).enum then
+        reg := changeregsize(reg1,S_W);
     end;
 end;
 
@@ -358,7 +358,12 @@ End.
 
 {
   $Log$
-  Revision 1.21  2003-03-28 19:16:57  peter
+  Revision 1.22  2003-06-03 21:09:05  peter
+    * internal changeregsize for optimizer
+    * fix with a hack to not remove the first instruction of a block
+      which will leave blockstart pointing to invalid memory
+
+  Revision 1.21  2003/03/28 19:16:57  peter
     * generic constructor working for i386
     * remove fixed self register
     * esi added as address register for i386
@@ -401,7 +406,7 @@ End.
       the parast, detected by tcalcst3 test
 
   Revision 1.13  2002/04/21 15:42:17  carl
-  * changeregsize -> rg.makeregsize
+  * changeregsize -> changeregsize
 
   Revision 1.12  2002/04/20 21:37:08  carl
   + generic FPC_CHECKPOINTER