Browse Source

- disable removal of dead loads before a call, because register
parameters are released before a call
* fix storeback of registers in case of different sizes (e.g., first
a "movl %eax,%edx" and later a "movb %dl,%al")

Jonas Maebe 21 years ago
parent
commit
6abc491796
2 changed files with 50 additions and 14 deletions
  1. 31 11
      compiler/i386/csopt386.pas
  2. 19 3
      compiler/i386/rropt386.pas

+ 31 - 11
compiler/i386/csopt386.pas

@@ -33,7 +33,7 @@ function CSE(asml: TAAsmoutput; first, last: tai; pass: longint): boolean;
 
 function doReplaceReg(hp: taicpu; newReg, orgReg: tsuperregister): boolean;
 function changeOp(var o: toper; newReg, orgReg: tsuperregister): boolean;
-function storeBack(p1: tai; orgReg, newReg: tsuperregister): boolean;
+function storeBack(start, current: tai; orgReg, newReg: tsuperregister): boolean;
 function NoHardCodedRegs(p: taicpu; orgReg, newReg: tsuperregister): boolean;
 function RegSizesOK(oldReg,newReg: tsuperregister; p: taicpu): boolean;
 
@@ -1135,17 +1135,27 @@ begin
 end;
 
 
-function storeBack(p1: tai; orgReg, newReg: tsuperregister): boolean;
+function storeBack(start, current: tai; orgReg, newReg: tsuperregister): boolean;
 { returns true if p1 contains an instruction that stores the contents }
 { of newReg back to orgReg                                            }
 begin
-  storeBack :=
-    (p1.typ = ait_instruction) and
-    (taicpu(p1).opcode = A_MOV) and
-    (taicpu(p1).oper[0]^.typ = top_reg) and
-    (getsupreg(taicpu(p1).oper[0]^.reg) = newReg) and
-    (taicpu(p1).oper[1]^.typ = top_reg) and
-    (getsupreg(taicpu(p1).oper[1]^.reg) = orgReg);
+  storeback := false;
+  if (current.typ = ait_instruction) and
+     (taicpu(current).opcode = A_MOV) and
+     (taicpu(current).oper[0]^.typ = top_reg) and
+     (getsupreg(taicpu(current).oper[0]^.reg) = newReg) and
+     (taicpu(current).oper[1]^.typ = top_reg) and
+     (getsupreg(taicpu(current).oper[1]^.reg) = orgReg) then
+    case taicpu(current).opsize of
+      S_B:
+        storeback := true;
+      S_W:
+        storeback := taicpu(start).opsize <> S_B;
+      S_L:
+        storeback := taicpu(start).opsize = S_L;
+      else
+        internalerror(2003121501);
+    end;
 end;
 
 
@@ -1196,7 +1206,7 @@ begin
           { if the newsupreg gets stored back to the oldReg, we can change }
           { "mov %oldReg,%newReg; <operations on %newReg>; mov %newReg, }
           { %oldReg" to "<operations on %oldReg>"                       }
-          removeLast := storeBack(endP, orgsupreg, newsupreg);
+          removeLast := storeBack(p,endP, orgsupreg, newsupreg);
           sequenceEnd :=
             { no support for (i)div, mul and imul with hardcoded operands }
             noHardCodedRegs(taicpu(endP),orgsupreg,newsupreg) and
@@ -1670,9 +1680,13 @@ begin
         ait_instruction:
           begin
             case taicpu(p).opcode of
+{
+     Does not work anymore with register calling because the registers are
+     released before the call
               A_CALL:
                 for regCounter := RS_EAX to RS_EBX do
                   removePrevNotUsedLoad(p,regCounter,true);
+}
               A_CLD: if GetLastInstruction(p, hp1) and
                         (ptaiprop(hp1.optinfo)^.DirFlag = F_NotSet) then
                        ptaiprop(tai(p).optinfo)^.CanBeRemoved := True;
@@ -2060,7 +2074,13 @@ end.
 
 {
   $Log$
-  Revision 1.56  2003-12-14 22:42:14  peter
+  Revision 1.57  2003-12-15 16:08:15  jonas
+    - disable removal of dead loads before a call, because register
+      parameters are released before a call
+    * fix storeback of registers in case of different sizes (e.g., first
+      a "movl %eax,%edx" and later a "movb %dl,%al")
+
+  Revision 1.56  2003/12/14 22:42:14  peter
     * fixed csdebug
 
   Revision 1.55  2003/12/14 14:18:59  peter

+ 19 - 3
compiler/i386/rropt386.pas

@@ -209,7 +209,7 @@ begin
           { if the newReg gets stored back to the oldReg, we can change }
           { "mov %oldReg,%newReg; <operations on %newReg>; mov %newReg, }
           { %oldReg" to "<operations on %oldReg>"                       }
-          switchLast := storeBack(endP,reg1,reg2);
+          switchLast := storeBack(start,endP,reg1,reg2);
           reg1StillUsed := reg1 in pTaiprop(endp.optinfo)^.usedregs;
           reg2StillUsed := reg2 in pTaiprop(endp.optinfo)^.usedregs;
           isInstruction := endp.typ = ait_instruction;
@@ -303,7 +303,17 @@ begin
           getNextInstruction(hp,hp);
         end;
       if switchLast then
-        doSwitchReg(taicpu(hp),reg1,reg2)
+        begin
+          { this is in case of a storeback, make sure the same size of register }
+          { contents as the initial move is transfered                          }
+          doSwitchReg(taicpu(hp),reg1,reg2);
+          if taicpu(hp).opsize <> taicpu(start).opsize then
+            begin
+              taicpu(hp).opsize := taicpu(start).opsize;
+              taicpu(hp).oper[0]^.reg := taicpu(start).oper[0]^.reg;
+              taicpu(hp).oper[1]^.reg := taicpu(start).oper[1]^.reg;
+            end;
+        end
       else
         getLastInstruction(hp,hp);
       allocRegBetween(asmL,newreg(R_INTREGISTER,reg1,R_SUBWHOLE),start,lastreg1);
@@ -350,7 +360,13 @@ End.
 
 {
   $Log$
-  Revision 1.24  2003-12-07 19:19:56  jonas
+  Revision 1.25  2003-12-15 16:08:16  jonas
+    - disable removal of dead loads before a call, because register
+      parameters are released before a call
+    * fix storeback of registers in case of different sizes (e.g., first
+      a "movl %eax,%edx" and later a "movb %dl,%al")
+
+  Revision 1.24  2003/12/07 19:19:56  jonas
     * fixed some more bugs which only showed up in a ppc cross compiler
 
   Revision 1.23  2003/11/22 00:40:19  jonas